/**
 @file drv_io.c

 @date 2010-02-26

 @version v5.1

 The file contains all driver I/O interface realization
*/

#if defined(TSINGMA) || defined(DUET2) || defined(TSINGMA_MX) || defined(TSINGMA_GX) || defined(ARCTIC)

#include "drv_api.h"
#include "usw/include/drv_io.h"
#include "usw/include/drv_ftm.h"
#include "usw/include/drv_error.h"
#include "usw/include/drv_chip_ctrl.h"
#include "usw/include/drv_common.h"
#include "usw/include/drv_sdb.h"
#include "usw/include/drv_ser.h"
#include "dal.h"

#define drv_memcpy(dst,src,size) {     \
    register uint32 loop = 0;                     \
    do                                            \
    {                                             \
        dst[loop] = src[loop];    \
        loop++;                                   \
    }while(loop < size);                         \
}
#define DS_QUEUE_MAP_TCAM_KEY_BYTES                    ((DRV_IS_DUET2(lchip) ? 8 : sizeof(DsQueueMapTcamKey_m)))

#define DRV_IF_FROM_TMM(lchip, operation)   \
        if (DRV_FROM_TMM(lchip))    {\
            operation;\
        }

#define DRV_TIME_OUT  1000    /* Time out setting */
#define DRV_DS_SIZE     64
#define DRV_PCI_ADDR_CTL  0x118

/* Tcam/Hash/Tbl/Reg I/O operation mutex control */
#define DRV_TBL_DYNAMIC(lchip, tbl_id) ((NULL != TABLE_EXT_INFO_PTR(lchip, tbl_id)) && (DRV_TABLE_TYPE_DYNAMIC == TABLE_EXT_INFO_TYPE(lchip, tbl_id)))
#if (SDK_WORK_PLATFORM == 0)
static uint32 parser_tbl_id_list[3][37] =
        {
            {
               ParserUdfCam_t                           ,
               ParserUdfCamResult_t                     ,
               ParserDebugStats_t                       ,
               ParserEthernetCtl_t                      ,
               ParserIpChecksumCtl_t                    ,
               ParserIpCtl_t                            ,
               ParserL3Ctl_t                            ,
               ParserLayer2ProtocolCam_t                ,
               ParserLayer2ProtocolCamValid_t           ,
               ParserLayer3FlexCtl_t                    ,
               ParserLayer3HashCtl_t                    ,
               ParserLayer3ProtocolCam_t                ,
               ParserLayer3ProtocolCamValid_t           ,
               ParserLayer3ProtocolCtl_t                ,
               ParserLayer4AchCtl_t                     ,
               ParserLayer4AppCtl_t                     ,
               ParserLayer4FlexCtl_t                    ,
               ParserMplsCtl_t                          ,
               ParserPacketTypeMap_t                    ,
               ParserPbbCtl_t                           ,
               ParserTrillCtl_t                         ,
               ParserReserved_t                         ,
               ParserRangeOpCtl_t,
               ParserLayer2ExtCam_t,
               DsParserLayer2Decoder_t,
               DsParserLayer3Decoder_t,
               DsParserLayer4Decoder_t,
               DsParserIntTcpCamResultCtl_t,
               DsParserIntUdpCamResultCtl_t,
               ParserInitDone_t,
               ParserInit_t,
               ParserLayer4ExtCam_t,
               DsL2Decoder_t,
               DsL3Decoder_t,
               DsL4Decoder_t,
               ParserUdfCtl_t,
               ParserPtpCtl_t
            },
            {
               ParserUdfCam1_t                           ,
               ParserUdfCamResult1_t                     ,
               ParserDebugStats1_t                       ,
               ParserEthernetCtl1_t                      ,
               ParserIpChecksumCtl_t                    ,
               ParserIpCtl1_t                            ,
               ParserL3Ctl1_t                            ,
               ParserLayer2ProtocolCam1_t                ,
               ParserLayer2ProtocolCamValid1_t           ,
               ParserLayer3FlexCtl1_t                    ,
               ParserLayer3HashCtl1_t                    ,
               ParserLayer3ProtocolCam1_t                ,
               ParserLayer3ProtocolCamValid1_t           ,
               ParserLayer3ProtocolCtl1_t                ,
               ParserLayer4AchCtl1_t                     ,
               ParserLayer4AppCtl1_t                     ,
               ParserLayer4FlexCtl1_t                    ,
               ParserMplsCtl1_t                          ,
               ParserPacketTypeMap1_t                    ,
               ParserPbbCtl1_t                           ,
               ParserTrillCtl1_t                         ,
               ParserReserved1_t                         ,
               ParserRangeOpCtl1_t,
               0,
               0,
               0,
               0,
               0,
               0,
               0,
               0,
               0,
               0
            },
            {
               ParserUdfCam2_t                           ,
               ParserUdfCamResult2_t                     ,
               ParserDebugStats2_t                       ,
               ParserEthernetCtl2_t                      ,
               ParserIpChecksumCtl2_t                    ,
               ParserIpCtl2_t                            ,
               ParserL3Ctl2_t                            ,
               ParserLayer2ProtocolCam2_t                ,
               ParserLayer2ProtocolCamValid2_t           ,
               ParserLayer3FlexCtl2_t                    ,
               ParserLayer3HashCtl2_t                    ,
               ParserLayer3ProtocolCam2_t                ,
               ParserLayer3ProtocolCamValid2_t           ,
               ParserLayer3ProtocolCtl2_t                ,
               ParserLayer4AchCtl2_t                     ,
               ParserLayer4AppCtl2_t                     ,
               ParserLayer4FlexCtl2_t                    ,
               ParserMplsCtl2_t                          ,
               ParserPacketTypeMap2_t                    ,
               ParserPbbCtl2_t                           ,
               ParserTrillCtl2_t                         ,
               ParserReserved2_t                         ,
               ParserRangeOpCtl2_t,
               0,
               0,
               0,
               0,
               0,
               0,
               0,
               0,
               0,
               0
            }
        };
#endif

uint8    g_usw_burst_en = FALSE; /* default use burst io */
#define DYNAMIC_TABLE_DO_RW(lchip, tbl_id)   (DYNAMIC_TABLE_UNIT_NUM(lchip, tbl_id)&&(DYNAMIC_MEM_SIZE(lchip, tbl_id) != TABLE_ENTRY_SIZE(lchip, tbl_id)))
extern uint8 drv_ser_get_tcam_scan_enable(uint8 lchip);

/**
 @brief Init embeded and external tcam mutex
*/
int32
drv_usw_chip_tcam_mutex_init(uint8 lchip)
{
    int32 ret;

#ifndef PACKET_TX_USE_SPINLOCK
    ret = sal_mutex_create(&p_drv_master[lchip]->p_entry_mutex);
#else
    ret = sal_spinlock_create((sal_spinlock_t**)&p_drv_master[lchip]->p_entry_mutex);
#endif
    if (ret || (!p_drv_master[lchip]->p_entry_mutex))
    {
        return DRV_E_FAIL_CREATE_MUTEX;
    }

    ret = sal_mutex_create(&p_drv_master[lchip]->p_tcam_write_mutex);
    if (ret || (!p_drv_master[lchip]->p_tcam_write_mutex))
    {
        return DRV_E_FAIL_CREATE_MUTEX;
    }

    ret = sal_mutex_create(&p_drv_master[lchip]->p_mep_mutex);
    if (ret || (!p_drv_master[lchip]->p_mep_mutex))
    {
        return DRV_E_FAIL_CREATE_MUTEX;
    }

        
#ifndef PACKET_TX_USE_SPINLOCK
    ret = sal_mutex_create(&p_drv_master[lchip]->p_sup1_entry_mutex);
#else
    ret = sal_spinlock_create((sal_spinlock_t**)&p_drv_master[lchip]->p_sup1_entry_mutex);
#endif
    if (ret || (!p_drv_master[lchip]->p_sup1_entry_mutex))
    {
        return DRV_E_FAIL_CREATE_MUTEX;
    }

    return DRV_E_NONE;
}

int32
drv_usw_chip_pci_mutex_init(uint8 lchip)
{
    int32 ret;

#ifndef PACKET_TX_USE_SPINLOCK
    ret = sal_mutex_create(&p_drv_master[lchip]->p_pci_mutex);
#else
    ret = sal_spinlock_create((sal_spinlock_t**)&p_drv_master[lchip]->p_pci_mutex);
#endif
    if (ret || (!p_drv_master[lchip]->p_pci_mutex))
    {
        return DRV_E_FAIL_CREATE_MUTEX;
    }

    return DRV_E_NONE;
}

int32
drv_usw_chip_i2c_mutex_init(uint8 lchip)
{
    int32 ret;

#ifndef PACKET_TX_USE_SPINLOCK
    ret = sal_mutex_create(&p_drv_master[lchip]->p_i2c_mutex);
#else
    ret = sal_spinlock_create((sal_spinlock_t**)&p_drv_master[lchip]->p_i2c_mutex);
#endif
    if (ret || (!p_drv_master[lchip]->p_i2c_mutex))
    {
        return DRV_E_FAIL_CREATE_MUTEX;
    }

    return DRV_E_NONE;
}

int32
drv_usw_chip_mmap_mutex_init(uint8 lchip)
{
    int32 ret;

#ifndef PACKET_TX_USE_SPINLOCK
    ret = sal_mutex_create(&p_drv_master[lchip]->p_mmap_mutex);
#else
    ret = sal_spinlock_create((sal_spinlock_t**)&p_drv_master[lchip]->p_mmap_mutex);
#endif
    if (ret || (!p_drv_master[lchip]->p_mmap_mutex))
    {
        return DRV_E_FAIL_CREATE_MUTEX;
    }

    return DRV_E_NONE;
}

int32
drv_usw_chip_hss_mutex_init(uint8 lchip)
{
    int32 ret;

    ret = sal_mutex_create(&p_drv_master[lchip]->p_hss_mutex);
    if (ret || (!p_drv_master[lchip]->p_hss_mutex))
    {
        return DRV_E_FAIL_CREATE_MUTEX;
    }

    return DRV_E_NONE;
}

int32
drv_usw_chip_acc_mutex_init(uint8 lchip)
{
    int32 ret;

    ret = sal_mutex_create(&p_drv_master[lchip]->fib_acc_mutex);
    if (ret || (!p_drv_master[lchip]->fib_acc_mutex))
    {
        return DRV_E_FAIL_CREATE_MUTEX;
    }

    ret = sal_mutex_create(&p_drv_master[lchip]->cpu_acc_mutex);
    if (ret || (!p_drv_master[lchip]->cpu_acc_mutex))
    {
        return DRV_E_FAIL_CREATE_MUTEX;
    }

    ret = sal_mutex_create(&p_drv_master[lchip]->ipfix_acc_mutex);
    if (ret || (!p_drv_master[lchip]->ipfix_acc_mutex))
    {
        return DRV_E_FAIL_CREATE_MUTEX;
    }

    ret = sal_mutex_create(&p_drv_master[lchip]->cid_acc_mutex);
    if (ret || (!p_drv_master[lchip]->cid_acc_mutex))
    {
        return DRV_E_FAIL_CREATE_MUTEX;
    }

    ret = sal_mutex_create(&p_drv_master[lchip]->mpls_acc_mutex);
    if (ret || (!p_drv_master[lchip]->mpls_acc_mutex))
    {
        return DRV_E_FAIL_CREATE_MUTEX;
    }

    ret = sal_mutex_create(&p_drv_master[lchip]->gemport_acc_mutex);
    if (ret || (!p_drv_master[lchip]->gemport_acc_mutex))
    {
        return DRV_E_FAIL_CREATE_MUTEX;
    }

    return DRV_E_NONE;
}

/**
 @brief Write sram direct read operation I/O,burst len :16
*/
inline int32
drv_usw_chip_write_sram_entry(uint8 lchip, uint64 addr,
                                uint32* data, int32 len)
{
    int32 i = 0;
    int32 tmp = 0;
    uint32 length = 0;
    uint8 shift_num = 0;
    uint8 shift_len = 0;
    uint8 done = 0;
#if (1 == SDK_WORK_PLATFORM)
#if (!defined(DUET2) && !defined(TSINGMA))
    extern int32 drv_model_write_sram_entry(uint8 lchip, uint64 pci_addr,  uint32* data, int32 len);
    extern int32 drv_mode_pci_addr_is_tcam(uint8 lchip, uint32 pci_addr);
    if (0 == drv_mode_pci_addr_is_tcam(lchip, addr))
    {
        return drv_model_write_sram_entry(lchip, addr, data, len);
    }
#endif
#endif
    /*for burst io*/
   tmp = (len >> 2);
   if(addr&0x3)
   {
      shift_num = 4;
      shift_len = 16;
    }
   else
   {
      shift_num = 0;
      shift_len = 1;
   }
    DRV_ENTRY_LOCK(lchip);
    do
    {
        length = (tmp>=shift_len)?shift_len:tmp;
        done =!p_drv_master[lchip]->drv_chip_write(DRV_MAP_LDEV(lchip), addr, length,  data + (i << shift_num));
        addr += (length << 2);
        tmp -= shift_len;
        i++;
    } while(done && (tmp > 0));
    DRV_ENTRY_UNLOCK(lchip);
    return (done?DRV_E_NONE:DRV_E_CMD_NOT_DONE);
}

/**
 @brief Real sram direct read operation I/O,burst len :16
*/
int32
drv_usw_chip_read_sram_entry(uint8 lchip, uint64 addr, uint32* data, int32 len)
{
    int32 i = 0;
    int32 tmp = 0;
    int32 length = 0;
    uint8 ldev = 0;
    uint8 shift_num = 0;
    uint8 shift_len = 0;
   uint8  done = 0;
#if (1 == SDK_WORK_PLATFORM)
#if (!defined(DUET2) && !defined(TSINGMA))
        extern int32 drv_model_read_sram_entry(uint8 lchip, uint64 pci_addr,  uint32* data, int32 len);
        extern int32 drv_mode_pci_addr_is_tcam(uint8 lchip, uint32 pci_addr);
        if (0 == drv_mode_pci_addr_is_tcam(lchip, addr))
        {
            return drv_model_read_sram_entry(lchip, addr, data, len);
        }
#endif
#endif

    /*for burst io*/
   ldev = DRV_MAP_LDEV(lchip);
   tmp = (len >> 2);
   if(addr&0x3)
   {
      shift_num = 4;
      shift_len = 16;
   }
   else
   {
      shift_num = 0;
      shift_len = 1;
   }

    DRV_ENTRY_LOCK(lchip);

    /*for burst write,no mask, max length is 16dword at one times*/
    do
    {
        length = (tmp>=shift_len)?shift_len:tmp;
        done = !p_drv_master[lchip]->drv_chip_read(ldev, addr, length, data + (i << shift_num));
        addr += (length << 2);
        tmp -= shift_len;
        i++;
    } while(done && (tmp > 0));

    DRV_ENTRY_UNLOCK(lchip);
    return (done?DRV_E_NONE:DRV_E_CMD_NOT_DONE);
}

/**
 @brief Real sram  write operation I/O ,burst len :64
*/
inline int32
drv_usw_chip_write_sram_entry2(uint8 lchip, uint64 addr, uint32* data, int32 len)
{
    int32 i = 0;
    int32 tmp = 0;
    uint32 length = 0;
    uint8 ldev = 0;
    uint8 shift_num = 0;
    uint8 shift_len = 0;
     uint8  done = 0;
#if (1 == SDK_WORK_PLATFORM)
#if (!defined(DUET2) && !defined(TSINGMA))
    extern int32 drv_model_write_sram_entry(uint8 lchip, uint64 pci_addr,  uint32* data, int32 len);
    extern int32 drv_mode_pci_addr_is_tcam(uint8 lchip, uint32 pci_addr);
    if (0 == drv_mode_pci_addr_is_tcam(lchip, addr))
    {
        return drv_model_write_sram_entry(lchip, addr, data, len);
    }
#endif
#endif
    /*for burst io*/
    tmp = (len >> 2);
    ldev = DRV_MAP_LDEV(lchip);
    if ( addr&0x3)
    {
        shift_num = 6;
        shift_len = 64;
    }
    else
    {
        shift_num = 0;
        shift_len = 1;
    }
    DRV_ENTRY_LOCK(lchip);
    do
    {
        length = (tmp >= shift_len)? shift_len : tmp;

        done  = !p_drv_master[lchip]->drv_chip_write_ext(ldev, addr, length,  data + (i << shift_num));
        addr += (length << 2);
        tmp -= shift_len;
        i++;
    }while (done && (tmp > 0));
    DRV_ENTRY_UNLOCK(lchip);
    return done ? DRV_E_NONE:DRV_E_CMD_NOT_DONE;
}

/**
 @brief Real sram read operation I/O ,burst len :64
*/
static inline int32
drv_usw_chip_read_sram_entry2(uint8 lchip, uint64 addr, uint32* data, int32 len, uint8 offset, uint16 real_len)
{
    int32 i = 0;
    int32 tmp = 0;
    int32 length = 0;
    uint8 ldev = 0;

    uint8 shift_num = 0;
    uint8 shift_len = 0;
    uint8 done = 0;
#if (1 == SDK_WORK_PLATFORM)
#if (!defined(DUET2) && !defined(TSINGMA))
        extern int32 drv_model_read_sram_entry(uint8 lchip, uint64 pci_addr,  uint32* data, int32 len);
        extern int32 drv_mode_pci_addr_is_tcam(uint8 lchip, uint32 pci_addr);
        addr = addr + offset;
        if (0 == drv_mode_pci_addr_is_tcam(lchip, addr))
        {
            return drv_model_read_sram_entry(lchip, addr, data, real_len);
        }
#endif
#endif

    /*for burst io*/
    ldev = DRV_MAP_LDEV(lchip);
    tmp = (len >> 2);
    if (addr&0x3)
    {
        shift_num = 6;
        shift_len = 64;

    }
    else
    {
        shift_num = 0;
        shift_len = 1;
    }

    DRV_SUP1_ENTRY_LOCK(lchip);

    /*for burst write,no mask, max length is 16dword at one times*/
    do
    {
        length = (tmp>=shift_len)?shift_len:tmp;
        done = !p_drv_master[lchip]->drv_chip_read_ext(ldev, addr, length, data + (i << shift_num), offset, (real_len-(i << shift_num)));
        addr += (length << 2);
        tmp -= shift_len;
        i++;
    }while (done&& (tmp > 0));
    DRV_SUP1_ENTRY_UNLOCK(lchip);
    return done ? DRV_E_NONE:DRV_E_CMD_NOT_DONE;
}

/*
cmd = (uint64)oper_bmp<<32|tbl_id
*/
int32
drv_ioctl_read_dma(uint8 lchip, uint32 index, uint64 cmd, void* p_val)
{
    void* p_dev_base = NULL;
    volatile uint32* addr_data = NULL;
    uint32 tbl_id = 0;
    uint32 hw_addr = 0;
    uint32 len = 0;
    uint32 offset = 0;
    uint16 oper_bmp = (cmd >> DRV_BITS_PER_WORD) & 0xFFF;

    DRV_MMAP_LOCK(lchip);
    /*get table address*/
    tbl_id = cmd & 0xFFFFFFFF;
    p_dev_base = p_drv_master[lchip]->dev_virt_addr;
    hw_addr =(TABLE_INFO(lchip, tbl_id).addrs[0]);
    hw_addr += index * (TABLE_INFO(lchip, tbl_id).entry_offset);
    addr_data = (volatile uint32*)((uint8*)p_dev_base + 0x100000 + (hw_addr & 0xFFFFC));
    /*
    word num
    0: 64
    1~63: 1~63
    if word num is more than 64, need read data more than once
    for dma tbl is less than 64 word reduce one if judgment
    */
    len = (TABLE_ENTRY_SIZE(lchip, tbl_id) >> 2);
    /* cfg cmd dma tbl base is 0x900000 */
    *(volatile uint32*)((uint8*)p_dev_base + 0x800) = (hw_addr & 0xFFF00000) | (oper_bmp << 8) | (len << 2) | 1;  /* brust read */
    /* read data */
    do{
        ((uint32*)p_val)[offset] = addr_data[offset];
    }while(++offset < len);
    if (*(volatile uint32*)((uint8*)p_dev_base + 0x81C))
    {
        hw_addr = *(uint32*)((uint8*)p_dev_base + 0x900);
        offset =  *(uint32*)((uint8*)p_dev_base + 0x904);
        DRV_DBG_INFO("memmap read error, MemMapLogAddr:0x%x, MemMapLogStatus:0x%x\n", hw_addr, offset);
        DRV_MMAP_UNLOCK(lchip);
        return DRV_E_PCI_CMD_ERROR;
    }
    DRV_MMAP_UNLOCK(lchip);

    return DRV_E_NONE;
}

/*
cmd = (uint64)oper_bmp<<32|tbl_id
*/
int32
drv_ioctl_write_dma(uint8 lchip, uint32 index, uint64 cmd, void* p_val)
{
    void* p_dev_base = NULL;
    volatile uint32* addr_data = NULL;
    uint32 tbl_id = 0;
    uint32 hw_addr = 0;
    uint32 len = 0;
    uint32 offset = 0;
    uint16 oper_bmp = (cmd >> DRV_BITS_PER_WORD) & 0xFFF;

    DRV_MMAP_LOCK(lchip);
    /*get table address*/
    tbl_id = cmd & 0xFFFFFFFF;
    p_dev_base = p_drv_master[lchip]->dev_virt_addr;
    hw_addr =(TABLE_INFO(lchip, tbl_id).addrs[0]);
    hw_addr += index * (TABLE_INFO(lchip, tbl_id).entry_offset);
    addr_data = (volatile uint32*)((uint8*)p_dev_base + 0x100000 + (hw_addr & 0xFFFFC));
    
    /*
    word num
    0: 64
    1~63: 1~63
    if word num is more than 64, need read data more than once
    for dma tbl is less than 64 word reduce one if judgment
    */
    len = (TABLE_ENTRY_SIZE(lchip, tbl_id) >> 2);
    /* cfg cmd dma tbl base is 0x900000 */
    *(volatile uint32*)((uint8*)p_dev_base + 0x800) = (hw_addr & 0xFFF00000) | (oper_bmp << 8) | (len << 2) | 1;  /* brust write */
    /* write data */
    do{
        addr_data[offset] = ((uint32*)p_val)[offset];
    }while(++offset < len);
    if (*(volatile uint32*)((uint8*)p_dev_base + 0x81C))
    {
        hw_addr = *(uint32*)((uint8*)p_dev_base + 0x900);
        offset =  *(uint32*)((uint8*)p_dev_base + 0x904);
        DRV_DBG_INFO("memmap read error, MemMapLogAddr:0x%x, MemMapLogStatus:0x%x\n", hw_addr, offset);
        DRV_MMAP_UNLOCK(lchip);
        return DRV_E_PCI_CMD_ERROR;
    }
    DRV_MMAP_UNLOCK(lchip);

    return DRV_E_NONE;
}

/*
cmd = (uint64)oper_bmp<<32|tbl_id
*/
int32
drv_ioctl_mask_write_dma(uint8 lchip, uint32 index, uint64 cmd, void* p_val)
{
    void* p_dev_base = NULL;
    volatile uint32* addr_mask = NULL;
    volatile uint32* addr_data = NULL;
    tbl_entry_t *entry = (tbl_entry_t*)p_val;
    uint32 tbl_id = 0;
    uint32 hw_addr = 0;
    uint32 len = 0;
    uint32 offset = 0;
    uint16 oper_bmp = (cmd >> DRV_BITS_PER_WORD) & 0xFFF;

    /*get table address*/
    tbl_id = cmd & 0xFFFFFFFF;
    p_dev_base = p_drv_master[lchip]->dev_virt_addr;
    hw_addr =(TABLE_INFO(lchip, tbl_id).addrs[0]);
    hw_addr += index * (TABLE_INFO(lchip, tbl_id).entry_offset);
    addr_mask = (volatile uint32*)((uint8*)p_dev_base + 0x800);
    addr_data = (volatile uint32*)((uint8*)p_dev_base + 0x100000 + (hw_addr & 0xFFFFC));
    /*
    word num
    0: 64
    1~63: 1~63
    if word num is more than 64, need read data more than once
    for dma tbl is less than 64 word reduce one if judgment
    */
    len = (TABLE_ENTRY_SIZE(lchip, tbl_id) >> 2);
    /* cfg mask */
    do{
        addr_mask[offset] = entry->mask_entry[offset];
    }while(++offset <  len);
    /* cfg cmd dma tbl base is 0x900000 */
    *(volatile uint32*)((uint8*)p_dev_base + 0x800) = (hw_addr & 0xFFF00000) | (oper_bmp << 8) | (len << 2) | 2;  /* mask write */
    /* write data */
    offset = 0;
    do{
        addr_data[offset] = entry->data_entry[offset];
    }while(++offset < len);
    if (*(volatile uint32*)((uint8*)p_dev_base + 0x81C))
    {
        hw_addr = *(uint32*)((uint8*)p_dev_base + 0x900);
        offset =  *(uint32*)((uint8*)p_dev_base + 0x904);
        DRV_DBG_INFO("memmap read error, MemMapLogAddr:0x%x, MemMapLogStatus:0x%x\n", hw_addr, offset);
        return DRV_E_PCI_CMD_ERROR;
    }

    return DRV_E_NONE;

}

/*
    drv_ioctl_read_sup1 used for DMACTL&Interrupt Module register access, this API used AxiSup1 interface.
    Notice:
    1) Perfermance API cannot used for dynamic table access
    2) Perfermance API cannot used for field access 
    3) for arctic cmd bitmap need encap ready
    4) for multi address table, must using instance index access mode
    5) only used for hw platform
    6) only support burst io
*/
int32
drv_ioctl_read_sup1(uint8 lchip, uint32 index, uint64 cmd, void* val)
{
    void* p_dev_base = NULL;
    tbls_id_t tbl_id;
    uint64 hw_addr = 0;    
    int32 i = 0;
    int32 tmp = 0;
    int32 length = 0;
    pci_cmd_status_u_t pci_cmd_status;
    uint32 pci_cmd_offset = 0;
    uint32 pci_cmd_timeout = 0;
    uint8 oper_bmp = 0;
    uint8 io_times = 0;

    tbl_id = DRV_IOC_MEMID(cmd);
    oper_bmp = (cmd >> DRV_BITS_PER_WORD) & 0xFF;
    p_dev_base = p_drv_master[lchip]->dev_virt_addr;

    /*get table address*/
    hw_addr =(TABLE_INFO(lchip, tbl_id).addrs[DRV_TBL_INS_OFFSET(index)]);       
    hw_addr += DRV_TBL_INS_INDEX(index) * (TABLE_INFO(lchip, tbl_id).entry_offset) + 1;    
    hw_addr = ((uint64)oper_bmp << DRV_BITS_PER_WORD) | hw_addr;

    /*dal read*/
    tmp = (TABLE_ENTRY_SIZE(lchip, tbl_id) >> 2);
    io_times = (tmp >> 4) + ((tmp & 0xF)? 1 : 0);

    DRV_SUP1_ENTRY_LOCK(lchip);    
   /*for burst write,no mask, max length is 16dword at one times*/
    do
    {
        length = (tmp>=16)?16:tmp;
        /*Check Last Operation */
         pci_cmd_status.val = *(volatile uint32*)((uint8*)p_dev_base + DAL_PCI_CMD1_STATUS);
         if( !pci_cmd_status.cmd_status.reqProcDone && pci_cmd_status.cmd_status.cmdDataLen)
         {
             pci_cmd_timeout  =0;
             do{
                 pci_cmd_status.val = *(volatile uint32*)((uint8*)p_dev_base + DAL_PCI_CMD1_STATUS);
             }while (!(pci_cmd_status.cmd_status.reqProcDone) && (++pci_cmd_timeout < PCIE_TIMEOUT));
             if(!pci_cmd_status.cmd_status.reqProcDone)
             {
                 DRV_DBG_INFO("The last PCIe I/O failed, Type:%s, lchip:%u, Addr:0x%x, CmdStatus:0x%.8x, ErrorCode:0x%x\n",pci_cmd_status.cmd_status.cmdReadType?"Read":"Write",
                             lchip, *(volatile uint32*)((uint8*)p_dev_base + DAL_PCI_ADDR1),
                             *(volatile uint32 *)((uint8 *)p_dev_base + DAL_PCI_CMD1_STATUS),
                             *(volatile uint32 *)((uint8 *)p_dev_base + DAL_PCI_DATA1_BUF));                 
                 DRV_SUP1_ENTRY_UNLOCK(lchip);    
                 return -1;
             }
         }

         /* 1. write CmdStatusReg */
         pci_cmd_status.val = 0;
         pci_cmd_status.cmd_status.cmdReadType = 1;
         pci_cmd_status.cmd_status.cmdEntryWords = (length == 16)? 0 : length;   /* normal operate only support 1 entry */
         pci_cmd_status.cmd_status.cmdDataLen = length;
         pci_cmd_status.val |= (((hw_addr >> 32) & 0x3F) << 16) | (((hw_addr >> 38) & 0x3) << 26);
         *(volatile uint32*)((uint8*)p_dev_base + DAL_PCI_CMD1_STATUS) = pci_cmd_status.val;
         *(volatile uint32*)((uint8*)p_dev_base + DAL_PCI_ADDR1) = hw_addr & 0xFFFFFFFF;
        
         pci_cmd_timeout = 0;
         do{
             pci_cmd_status.val = *(volatile uint32*)((uint8*)p_dev_base + DAL_PCI_CMD1_STATUS);
         }while (!(pci_cmd_status.cmd_status.reqProcDone) && (++pci_cmd_timeout < PCIE_TIMEOUT));
        
         if(!pci_cmd_status.cmd_status.reqProcDone || pci_cmd_status.cmd_status.reqProcError)
         {
           DRV_DBG_INFO("PCIe Read failed, lchip:%u, Addr:0x%.8x, bmp:0x%x, CmdStatus:0x%.8x, ErrorCode:0x%x\n",
                             lchip, *(volatile uint32*)((uint8*)p_dev_base + DAL_PCI_ADDR1), (uint32)(hw_addr >> 32),
                             *(volatile uint32*)((uint8*)p_dev_base + DAL_PCI_CMD1_STATUS),
                             *(volatile uint32*)((uint8*)p_dev_base + DAL_PCI_DATA1_BUF));           
           DRV_SUP1_ENTRY_UNLOCK(lchip);    
           return -1;
         }
        
         pci_cmd_offset = 0;
         /* this mode is usual mode, for support mmap device access */
         do{
             *((uint32*)val + (i<<4) + pci_cmd_offset) = *(volatile uint32*)((uint8*)p_dev_base + DAL_PCI_DATA1_BUF + (pci_cmd_offset << 2));
             pci_cmd_offset += 1;
         }while (--length);
        
        hw_addr += (length << 2);
        tmp -= 16;
        i++;
    } while(i < io_times);
    DRV_SUP1_ENTRY_UNLOCK(lchip);    
    
    return DRV_E_NONE;
}

/*
    drv_ioctl_write_sup1 used for DMACTL&Interrupt Module register access, this API used AxiSup1 interface.
    Notice:
    1) Perfermance API cannot used for dynamic table access
    2) Perfermance API cannot used for field access 
    3) for arctic cmd bitmap need encap ready
    4) for multi address table, must using instance index access mode
    5) only used for hw platform
    6) only support burst io
*/
int32
drv_ioctl_write_sup1(uint8 lchip, uint32 index, uint64 cmd, void* val)
{    
    void* p_dev_base = NULL;
    tbls_id_t tbl_id;
    uint64 hw_addr = 0;    
    int32 i = 0;
    int32 tmp = 0;
    int32 length = 0;
    pci_cmd_status_u_t pci_cmd_status;
    uint32 pci_cmd_offset = 0;
    uint32 pci_cmd_timeout = 0;
    uint16 oper_bmp = 0;
    uint8 io_times = 0;

    tbl_id = DRV_IOC_MEMID(cmd);
    oper_bmp = (cmd >> DRV_BITS_PER_WORD) & 0xFFF;
    p_dev_base = p_drv_master[lchip]->dev_virt_addr;

    /*get table address*/
    hw_addr =(TABLE_INFO(lchip, tbl_id).addrs[DRV_TBL_INS_OFFSET(index)]);       
    hw_addr += DRV_TBL_INS_INDEX(index) * (TABLE_INFO(lchip, tbl_id).entry_offset) + 1;    
    hw_addr = ((uint64)oper_bmp << DRV_BITS_PER_WORD) | hw_addr;

    /*dal write*/
    tmp = (TABLE_ENTRY_SIZE(lchip, tbl_id) >> 2);
    io_times = (tmp >> 4) + ((tmp & 0xF)? 1 : 0);

    DRV_SUP1_ENTRY_LOCK(lchip);    
   /*for burst write,no mask, max length is 16dword at one times*/
    do
    {
        length = (tmp>=16)?16:tmp;
        /*Check Last Operation */
         pci_cmd_status.val = *(volatile uint32*)((uint8*)p_dev_base + DAL_PCI_CMD1_STATUS);
         if( !pci_cmd_status.cmd_status.reqProcDone && pci_cmd_status.cmd_status.cmdDataLen)
         {
             pci_cmd_timeout  =0;
             do{
                 pci_cmd_status.val = *(volatile uint32*)((uint8*)p_dev_base + DAL_PCI_CMD1_STATUS);
             }while (!(pci_cmd_status.cmd_status.reqProcDone) && (++pci_cmd_timeout < PCIE_TIMEOUT));
             if(!pci_cmd_status.cmd_status.reqProcDone)
             {
                 DRV_DBG_INFO("The last PCIe I/O failed, Type:%s, lchip:%u, Addr:0x%x, CmdStatus:0x%.8x, ErrorCode:0x%x\n",pci_cmd_status.cmd_status.cmdReadType?"Read":"Write",
                             lchip, *(volatile uint32*)((uint8*)p_dev_base + DAL_PCI_ADDR1),
                             *(volatile uint32 *)((uint8 *)p_dev_base + DAL_PCI_CMD1_STATUS),
                             *(volatile uint32 *)((uint8 *)p_dev_base + DAL_PCI_DATA1_BUF));                 
                 DRV_SUP1_ENTRY_UNLOCK(lchip);    
                 return -1;
             }
         }

        pci_cmd_status.val = 0;
        pci_cmd_status.cmd_status.cmdReadType = 0;
        pci_cmd_status.cmd_status.cmdEntryWords = (length == 16)? 0 : length;   /* normal operate only support 1 entry */
        pci_cmd_status.cmd_status.cmdDataLen = length;
        pci_cmd_status.val |= (((hw_addr >> 32) & 0x3F) << 16) | (((hw_addr >> 38) & 0x3) << 26);
        *(volatile uint32*)((uint8*)p_dev_base + DAL_PCI_CMD1_STATUS) = pci_cmd_status.val;
        *(volatile uint32*)((uint8*)p_dev_base + DAL_PCI_ADDR1) = hw_addr & 0xFFFFFFFF;

        pci_cmd_offset = 0;
        do{
            *(volatile uint32*)((uint8*)p_dev_base + DAL_PCI_DATA1_BUF + (pci_cmd_offset << 2)) = *((uint32*)val+pci_cmd_offset);
            pci_cmd_offset += 1;
        }while (--length);

        
        hw_addr += (length << 2);
        tmp -= 16;
        i++;
    } while(i < io_times);
    DRV_SUP1_ENTRY_UNLOCK(lchip);    
    
    return DRV_E_NONE;
}

INLINE int32
drv_usw_chip_convert_tcam_dump_content(uint8 lchip, uint32 tcam_entry_width, uint32 *data, uint32 *mask, uint8* p_empty)
{
    uint32 index = 0;
    uint32 mask_tmp = 0;
     uint8 loop_cnt = 0;
#if (SDK_WORK_PLATFORM == 1)
        return DRV_E_NONE;
#endif
   loop_cnt = (tcam_entry_width + 31) >> 5;
   do
   {
       mask_tmp = (mask[index] ^ data[index]);
       data[index] =  (mask_tmp & data[index]);
       mask[index] = mask_tmp;
       index++;
   }while(index <loop_cnt);

    return DRV_E_NONE;
}


/**
 @brief The function read table data from a sram memory location, for static and tcam ad
*/
int32
drv_usw_chip_sram_tbl_read2(uint8 lchip, uint32 index, uint32 cmd, uint8 oper_bmp, uint32* data)
{
    uint32 start_data_addr = 0;
    uint32 index_drv = 0;
    uint32 tbl_id = 0;
    uint8 burst_op = 0;

    tbl_id = DRV_IOC_MEMID(cmd);
    index_drv = (index >>24) * TABLE_MAX_INDEX(lchip, tbl_id) / TABLE_ADDR_NUM(lchip, tbl_id) + (index & 0xFFFFFF);
    if (index_drv >= TABLE_MAX_INDEX(lchip, tbl_id))
    {
        DRV_DBG_INFO("\nERROR! Index-0x%x exceeds the max_index 0x%x! TblID: %d, Name:%s, file:%s line:%d function:%s\n",
                     index_drv,TABLE_MAX_INDEX(lchip, tbl_id), tbl_id, TABLE_NAME(lchip, tbl_id), __FILE__, __LINE__, __FUNCTION__);
        return DRV_E_INVALID_INDEX;
    }

#if (SDB_DISABLE != SDB_MODE)
    if (DRV_READ_MEM_FROM_SER(tbl_id))
    {
        uint32 tmp = 0;
        if (TABLE_EXT_INFO_PTR(lchip, tbl_id) && TABLE_EXT_INFO_TYPE(lchip, tbl_id) == DRV_TABLE_TYPE_DYNAMIC)
        {
            tmp = DYNAMIC_TABLE_UNIT_SIZE(lchip, tbl_id);
        }
        else
        {
            tmp = TABLE_INFO(lchip, tbl_id).tcam_mem ? TABLE_ENTRY_OFFSET(lchip, tbl_id): TABLE_ENTRY_SIZE(lchip, tbl_id);
        }
        sal_memcpy(data, (uint8*)drv_sdb_read(lchip, tbl_id, index_drv, tmp, oper_bmp), TABLE_ENTRY_SIZE(lchip, tbl_id));
        return DRV_E_NONE;
    }
#endif

    if (!TABLE_EXT_INFO_PTR(lchip, tbl_id) || (TABLE_EXT_TYPE(lchip, tbl_id) == 1))
    {
        /*for static table*/
        drv_usw_table_get_static_hw_addr(lchip, tbl_id, index, &start_data_addr);
    }
    else
    {
        /*for tcam ad table*/
#if (SDK_WORK_PLATFORM == 1)
        drv_usw_table_get_tcam_ad_hw_addr(lchip, tbl_id, index, &start_data_addr);
#else
        drv_usw_table_get_tcam_ad_hw_addr1(lchip, tbl_id, index, &start_data_addr);
#endif
    }

    burst_op = !(TABLE_OP_TYPE(lchip, tbl_id)&Op_DisBurst) && p_drv_master[lchip]->burst_en;
    start_data_addr = start_data_addr + burst_op;
#if (SDK_WORK_PLATFORM == 0)
    return drv_usw_chip_read_sram_entry2(lchip, ((uint64)oper_bmp << DRV_BITS_PER_WORD) | start_data_addr, data, TABLE_ENTRY_SIZE(lchip, tbl_id), 0 , (TABLE_ENTRY_SIZE(lchip, tbl_id) >> 2));
#else
    return drv_usw_chip_read_sram_entry(lchip, ((uint64)oper_bmp << DRV_BITS_PER_WORD) | start_data_addr, data, TABLE_ENTRY_SIZE(lchip, tbl_id));
#endif
}

/**
 @brief The function write table data to a sram memory location
  the general API interface,: all static table & tcam ad
*/
int32
drv_usw_chip_sram_tbl_write2(uint8 lchip, uint32 index, uint32 cmd, uint8 oper_bmp, uint32* data)
{
    int32 ret = DRV_E_NONE;
    uint32 index_drv = 0;
    uint32 local_max_index = 0;
    uint32 tbl_id = 0;

#ifdef WARMBOOT
   if(p_drv_master[lchip]->wb_status == DRV_WB_STATUS_RELOADING)
    {
        return DRV_E_NONE;
    }
#endif
    tbl_id = DRV_IOC_MEMID(cmd);
    /* check if the index num exceed the max index num of the tbl */
    local_max_index = TABLE_MAX_INDEX(lchip, tbl_id) / TABLE_ADDR_NUM(lchip, tbl_id);
    index_drv = (index >>24) * local_max_index + (index & 0xFFFFFF);
    if (index_drv >= TABLE_MAX_INDEX(lchip, tbl_id))
    {
        DRV_DBG_INFO("\nERROR! Index-0x%x exceeds the max_index 0x%x! TblID: %d, Name:%s\n",
                     index_drv, TABLE_MAX_INDEX(lchip, tbl_id) , tbl_id, TABLE_NAME(lchip, tbl_id));
        return DRV_E_INVALID_INDEX;
    }
#if (SDB_MEM_MODEL != SDB_MODE)
{
    
#if (SDK_WORK_PLATFORM == 0)  
    uint32 burst_op = 0;
#endif
    uint32 start_data_addr = 0;


  #if (SDK_WORK_PLATFORM == 0)  
    burst_op = !(TABLE_OP_TYPE(lchip, tbl_id)&Op_DisBurst) && p_drv_master[lchip]->burst_en;
    if(!TABLE_EXT_INFO_PTR(lchip, tbl_id) || (TABLE_EXT_TYPE(lchip, tbl_id) != 1))
    {
        int32   tmp = 0;
        uint32  length = 0;
        uint8   ldev = 0;
        uint8   done = 0;
        uint8   shift_num = 0;
        uint8   shift_len = 0;
        uint8   loop = 0;

        if (!TABLE_EXT_INFO_PTR(lchip, tbl_id))
        {
            /*for static table*/
            drv_usw_table_get_static_hw_addr(lchip, tbl_id, index, &start_data_addr);
        }
        else
        {
            /*for tcam ad table*/
#if (SDK_WORK_PLATFORM == 1)
            drv_usw_table_get_tcam_ad_hw_addr(lchip, tbl_id, index, &start_data_addr);
#else
            drv_usw_table_get_tcam_ad_hw_addr1(lchip, tbl_id, index, &start_data_addr);
#endif
        }
        
        start_data_addr = start_data_addr + burst_op;
            
        tmp = (TABLE_ENTRY_SIZE(lchip, tbl_id) >> 2);
        loop = 0;
        ldev = DRV_MAP_LDEV(lchip);
        shift_num = burst_op?6:0;
        shift_len = burst_op?64:1;
        if (burst_op)
        {
            shift_num = 6;
            shift_len = 64;
        }
        else
        {
            shift_num = 0;
            shift_len = 1;
        }

        DRV_ENTRY_LOCK(lchip);
        do
        {
            length = (tmp >= shift_len)? shift_len : tmp;        
            done  = !p_drv_master[lchip]->drv_chip_write_ext(ldev, ((uint64)oper_bmp << DRV_BITS_PER_WORD) | start_data_addr, length,  data + (loop << shift_num));
            start_data_addr += (length << 2);
            tmp -= shift_len;
            loop++;
        }while (done && (tmp > 0));
        DRV_ENTRY_UNLOCK(lchip);   
        ret = !done?DRV_E_CMD_NOT_DONE:ret;   
    }
    else if(TABLE_EXT_TYPE(lchip, tbl_id) == 1)  /*parser table*/
    {
        uint32 tbl_offset =0 ;
        uint32 tmp = 0;
        index_drv = index % local_max_index;

        for(tbl_offset=0; tbl_offset < (sizeof(parser_tbl_id_list[0])>>2); tbl_offset++)
        {
            if(tbl_id == parser_tbl_id_list[0][tbl_offset])
            {
                break;
            }
        }

        if(tbl_offset == sizeof(parser_tbl_id_list[0])>>2)
        {
            DRV_DBG_INFO("ERROR! (drv_usw_write_sram_tbl): chip-0x%x, tbl-0x%x, index-0x%x is not an parser table\n",
                    lchip, tbl_id, index);
            return DRV_E_INVALID_TBL;
        }

        
        tmp = index_drv * TABLE_ENTRY_OFFSET(lchip, tbl_id) + (!(TABLE_OP_TYPE(lchip, tbl_id)&Op_DisBurst) && p_drv_master[lchip]->burst_en);
        start_data_addr = TABLE_DATA_BASE(lchip, parser_tbl_id_list[0][tbl_offset], 2) + tmp;
        DRV_IF_ERROR_RETURN(drv_usw_chip_write_sram_entry2(lchip, ((uint64)oper_bmp << DRV_BITS_PER_WORD) | start_data_addr, data, TABLE_ENTRY_SIZE(lchip, tbl_id)));
#if (SDB_DISABLE != SDB_MODE)
        DRV_MCHIP_SDB_API(lchip)->drv_sdb_write_api(lchip, parser_tbl_id_list[0][tbl_offset], index_drv+2*local_max_index, data, TABLE_ENTRY_SIZE(lchip, tbl_id), oper_bmp);
#endif
        start_data_addr = TABLE_DATA_BASE(lchip, parser_tbl_id_list[0][tbl_offset], 1) + tmp;
        DRV_IF_ERROR_RETURN(drv_usw_chip_write_sram_entry2(lchip, ((uint64)oper_bmp << DRV_BITS_PER_WORD) | start_data_addr, data, TABLE_ENTRY_SIZE(lchip, tbl_id)));
#if (SDB_DISABLE != SDB_MODE)
        DRV_MCHIP_SDB_API(lchip)->drv_sdb_write_api(lchip, parser_tbl_id_list[0][tbl_offset], index_drv+local_max_index, data, TABLE_ENTRY_SIZE(lchip, tbl_id), oper_bmp);
#endif
        start_data_addr = TABLE_DATA_BASE(lchip, parser_tbl_id_list[0][tbl_offset], 0) + tmp;

        ret  = drv_usw_chip_write_sram_entry2(lchip, ((uint64)oper_bmp << DRV_BITS_PER_WORD) | start_data_addr, data, TABLE_ENTRY_SIZE(lchip, tbl_id));
#if (SDB_DISABLE != SDB_MODE)
        DRV_MCHIP_SDB_API(lchip)->drv_sdb_write_api(lchip, parser_tbl_id_list[0][tbl_offset], index_drv, data, TABLE_ENTRY_SIZE(lchip, tbl_id), oper_bmp);
#endif

    }
#else
    drv_usw_table_get_hw_addr(lchip, tbl_id, index, &start_data_addr, 0);
    ret  = drv_usw_chip_write_sram_entry2(lchip, ((uint64)oper_bmp << DRV_BITS_PER_WORD) | start_data_addr, data, TABLE_ENTRY_SIZE(lchip, tbl_id));
 #endif
}
#endif

#if (SDB_DISABLE != SDB_MODE)
{    
    if (!ret && g_sdb_master[lchip] && g_sdb_master[lchip]->sdb_en)
    {
        uint32 tmp = 0;
        if (TABLE_EXT_INFO_PTR(lchip, tbl_id) && TABLE_EXT_INFO_TYPE(lchip, tbl_id) == DRV_TABLE_TYPE_DYNAMIC)
        {
            tmp = DYNAMIC_TABLE_UNIT_SIZE(lchip, tbl_id);
        }
        else
        {
            tmp = TABLE_INFO(lchip, tbl_id).tcam_mem? TABLE_ENTRY_OFFSET(lchip, tbl_id): TABLE_ENTRY_SIZE(lchip, tbl_id);
        }
        ret = DRV_MCHIP_SDB_API(lchip)->drv_sdb_write_api(lchip, tbl_id, index_drv, data, tmp, oper_bmp);
    }
}
#endif

    return ret;
}

int32
drv_usw_chip_sram_tbl_write3(uint8 lchip, uint32 index, uint32 cmd, uint8 oper_bmp, uint32* data)
{
    int32 ret = 0;
    uint32 tbl_id = 0;

    tbl_id = DRV_IOC_MEMID(cmd);
    /*pp id 2 default bypassIpePHTMode set 1*/
    if ((tbl_id == IpeFwdCtl_t) &&  (((oper_bmp) & 0x10) ? 1 : 0))
    {
        oper_bmp &= ~0x10;
        SetIpeFwdCtl(V, bypassIpePHTMode_f, data, 0);
        ret = drv_usw_chip_sram_tbl_write2(lchip, index, cmd, oper_bmp, data);
        SetIpeFwdCtl(V, bypassIpePHTMode_f, data, 1);
        oper_bmp &= ~0x3C;
        oper_bmp |= 0x10;
    }
    else if ((tbl_id == IpeHeaderAdjustCtl_t) &&  (((oper_bmp) & (1<<4)) ? 1 : 0))
    {
        oper_bmp &= ~0x10;
        SetIpeHeaderAdjustCtl(V, bypassIpePHTMode_f, data, 0);
        ret = drv_usw_chip_sram_tbl_write2(lchip, index, cmd, oper_bmp, data);
        SetIpeHeaderAdjustCtl(V, bypassIpePHTMode_f, data, 1);
        oper_bmp &= ~0x3C;
        oper_bmp |= 0x10;
    }

    ret = ret ?  ret : drv_usw_chip_sram_tbl_write2(lchip, index, cmd, oper_bmp, data);

    return ret;
}

/**
 @brief The function read table data from a sram memory location
*/
int32
drv_usw_chip_dyn_tbl_read2(uint8 lchip, uint32 index, uint32 cmd, uint8 oper_bmp, uint32* data)
{
    uint32 start_data_addr = 0;
    uint32 idx_base = 0;
    uint32 entry_offset = 0;
    uint8 loop = 0;
    uint8  addr_offset = 0;
    uint32 tbl_id = 0;
    dynamic_mem_allocate_info_t* p_dyn_alloc = NULL; 
#if (0 == SDK_WORK_PLATFORM)
    uint8  done = 0;
    uint8   ldev = 0;
#endif

    tbl_id = DRV_IOC_MEMID(cmd);
#if (1 == SDK_WORK_PLATFORM)
     addr_offset += TABLE_ADDR_NUM(lchip, tbl_id);
#endif
    entry_offset = TABLE_ENTRY_OFFSET(lchip, tbl_id);
    p_dyn_alloc = (dynamic_mem_allocate_info_t*)&(DYNAMIC_EXT_INFO_PTR(lchip, tbl_id)->dynamic_mem_allocate_info);

    do
    {
        if (index <= p_dyn_alloc->end_index[loop])
        {
            start_data_addr = p_dyn_alloc->dynamic_mem_hw_data_base[p_dyn_alloc->block_id[loop]][addr_offset];
            break;
        }
        loop++;
    }while( loop < p_dyn_alloc->block_num);

  /* check if the index num exceed the max index num of the tbl */
  if(0 == start_data_addr)
  {
    idx_base = (index >>24) * TABLE_MAX_INDEX(lchip, tbl_id) / TABLE_ADDR_NUM(lchip, tbl_id) + (index & 0xFFFFFF);
      DRV_DBG_INFO("\nERROR! Index-0x%x exceeds the max_index 0x%x! TblID: %d, Name:%s\n",
                     idx_base, TABLE_MAX_INDEX(lchip, tbl_id) , tbl_id, TABLE_NAME(lchip, tbl_id));
       return DRV_E_INVALID_INDEX;
  }

#if (SDB_DISABLE != SDB_MODE)
    if (DRV_READ_MEM_FROM_SER(tbl_id))
    {
        entry_offset    = DYNAMIC_TABLE_UNIT_SIZE(lchip, tbl_id);
        sal_memcpy(data, (uint8*)drv_sdb_read(lchip, tbl_id, index, entry_offset, oper_bmp), TABLE_ENTRY_SIZE(lchip, tbl_id));
        return DRV_E_NONE;
    }
#endif

  idx_base =  (index - p_dyn_alloc->start_index[loop]) / p_dyn_alloc->unit_num;
  start_data_addr  += idx_base * entry_offset ;

    if (p_dyn_alloc->unit_num > 1)
    {
    uint8 offset = index % DYNAMIC_TABLE_UNIT_NUM(lchip, tbl_id);
#if (1 == SDK_WORK_PLATFORM)
       drv_usw_table_get_dyn_hw_addr(lchip, tbl_id, index, &start_data_addr);
       start_data_addr += DYNAMIC_TABLE_UNIT_SIZE(lchip, tbl_id) * offset;
       return drv_usw_chip_read_sram_entry(lchip, ((uint64)oper_bmp << DRV_BITS_PER_WORD) | start_data_addr, data, TABLE_ENTRY_SIZE(lchip, tbl_id));
#else
       ldev = DRV_MAP_LDEV(lchip);
       start_data_addr += 0x01; /*burst */
       offset = offset * p_dyn_alloc->unit_size;

       DRV_SUP1_ENTRY_LOCK(lchip);
       done = !p_drv_master[lchip]->drv_chip_read_ext(ldev, ((uint64)oper_bmp << DRV_BITS_PER_WORD) | start_data_addr, (p_dyn_alloc->mem_size >> 2), data, offset, (TABLE_ENTRY_SIZE(lchip, tbl_id)>>2));
       DRV_SUP1_ENTRY_UNLOCK(lchip);

       return done ? DRV_E_NONE:DRV_E_CMD_NOT_DONE;
#endif
   }
    else
    {
#if (1 == SDK_WORK_PLATFORM)
        return drv_usw_chip_read_sram_entry(lchip, ((uint64)oper_bmp << DRV_BITS_PER_WORD) | start_data_addr, data,TABLE_ENTRY_SIZE(lchip, tbl_id));
#else
        ldev = DRV_MAP_LDEV(lchip);
        start_data_addr += 0x01; /*burst */
        
        DRV_SUP1_ENTRY_LOCK(lchip);
        done = !p_drv_master[lchip]->drv_chip_read_ext(ldev, ((uint64)oper_bmp << DRV_BITS_PER_WORD) | start_data_addr, (TABLE_ENTRY_SIZE(lchip, tbl_id) >> 2), data, 0, (TABLE_ENTRY_SIZE(lchip, tbl_id)>>2));
        DRV_SUP1_ENTRY_UNLOCK(lchip);
        
        return done ? DRV_E_NONE:DRV_E_CMD_NOT_DONE;
#endif
    }
    return DRV_E_NONE;
}

int32
drv_usw_chip_dyn_tbl_lpm(uint8 lchip, uint32 index, uint32 cmd, uint8 oper_bmp, uint32* data)
{
    dynamic_mem_allocate_info_t* p_dyn_alloc = NULL;
    int32 ret = DRV_E_NONE;
    uint32 tbl_id = 0;
#if (0 == SDK_WORK_PLATFORM)
    uint32 buf[64] = {0};
#endif
#if (SDB_MEM_MODEL != SDB_MODE)
#if (0 == SDK_WORK_PLATFORM)
    tbl_entry_t* p_data = (tbl_entry_t*)data;
    uint8 count = 0;
    uint8   ldev = 0;
    uint8   done = 0;
#endif
    uint32 start_data_addr = 0;
    uint8   loop = 0;
    uint8   addr_offset = 0;
    uint8   unit_num = 0; 
#endif

#ifdef WARMBOOT
   if(p_drv_master[lchip]->wb_status == DRV_WB_STATUS_RELOADING)
    {
        return DRV_E_NONE;
    }
#endif
    tbl_id = DRV_IOC_MEMID(cmd);
    p_dyn_alloc = (dynamic_mem_allocate_info_t*)&(DYNAMIC_EXT_INFO_PTR(lchip, tbl_id)->dynamic_mem_allocate_info);
#if (SDB_MEM_MODEL != SDB_MODE)
{
#if (1 == SDK_WORK_PLATFORM)
    addr_offset += TABLE_ADDR_NUM(lchip, tbl_id);
#else
    addr_offset = DRV_TBL_INS_OFFSET(index);
#endif

    do
    {
        if (index <= p_dyn_alloc->end_index[loop])
        {
            start_data_addr = p_dyn_alloc->dynamic_mem_hw_data_base[p_dyn_alloc->block_id[loop]][addr_offset];
            break;
        }
        loop++;
    }while( loop < p_dyn_alloc->block_num);

   /* check if the index num exceed the max index num of the tbl */
   if(start_data_addr == 0)
   {
       DRV_DBG_INFO("\nERROR! Index-0x%x exceeds the max_index 0x%x! TblID: %d, Name:%s\n",
                    index, TABLE_MAX_INDEX(lchip, tbl_id) , tbl_id, TABLE_NAME(lchip, tbl_id));
       return DRV_E_INVALID_INDEX;
   }

    unit_num = p_dyn_alloc->unit_num;
    start_data_addr +=  ((index - p_dyn_alloc->start_index[loop]) / unit_num) * TABLE_ENTRY_OFFSET(lchip, tbl_id);

#if (1 == SDK_WORK_PLATFORM)
   ret = drv_usw_chip_write_sram_entry2(lchip, ((uint64)oper_bmp << DRV_BITS_PER_WORD) | start_data_addr, data, TABLE_ENTRY_SIZE(lchip, tbl_id));
#else
    ldev = DRV_MAP_LDEV(lchip);
    addr_offset = (index % unit_num) * (p_dyn_alloc->unit_size >> 2);
    loop = (TABLE_ENTRY_SIZE(lchip, tbl_id) >> 2);
    do
    {
        buf[(addr_offset << 1) + (count << 1)] = p_data->mask_entry[count];
        buf[(addr_offset << 1) + (count << 1) + 1] = p_data->data_entry[count];
        count++;
    } while (--loop);

    start_data_addr += 2;

    DRV_ENTRY_LOCK(lchip);
    done  = !p_drv_master[lchip]->drv_chip_write_ext(ldev, ((uint64)oper_bmp << DRV_BITS_PER_WORD)|start_data_addr, (p_dyn_alloc->mem_size >> 1), buf);
    DRV_ENTRY_UNLOCK(lchip);
    ret = !done?DRV_E_CMD_NOT_DONE:ret;
#endif
}
#endif

#if (SDB_DISABLE != SDB_MODE)
    if (!ret && g_sdb_master[lchip] && g_sdb_master[lchip]->sdb_en)
    {
#if (1 == SDK_WORK_PLATFORM)
        ret = DRV_MCHIP_SDB_API(lchip)->drv_sdb_write_api(lchip, tbl_id, index, data, p_dyn_alloc->unit_size, oper_bmp);
#else
        ret = DRV_MCHIP_SDB_API(lchip)->drv_sdb_write_api(lchip, tbl_id, ((1<<31) | index), buf, (p_dyn_alloc->unit_size<<1), oper_bmp);
#endif
    }
#endif
    return ret;
}

int32
drv_usw_chip_dyn_tbl_mask_write2(uint8 lchip, uint32 index, uint32 cmd, uint8 oper_bmp, uint32* data)
{
    dynamic_mem_allocate_info_t* p_dyn_alloc = NULL;
    int32 ret = DRV_E_NONE;
    uint32 tbl_id = 0;
#if (SDB_MEM_MODEL != SDB_MODE)
#if (0 == SDK_WORK_PLATFORM)
    uint32 buf[64] = {0};
    uint8 count = 0;
    uint8   ldev = 0;
#endif
    uint32 start_data_addr = 0;
    uint8   loop = 0;
    uint8   addr_offset = 0;
#endif

#ifdef WARMBOOT
   if(p_drv_master[lchip]->wb_status == DRV_WB_STATUS_RELOADING)
    {
        return DRV_E_NONE;
    }
#endif
    tbl_id = DRV_IOC_MEMID(cmd);
    p_dyn_alloc = (dynamic_mem_allocate_info_t*)&(DYNAMIC_EXT_INFO_PTR(lchip, tbl_id)->dynamic_mem_allocate_info);
#if (SDB_MEM_MODEL != SDB_MODE)
{
#if (1 == SDK_WORK_PLATFORM)
    addr_offset += TABLE_ADDR_NUM(lchip, tbl_id);
#endif
        do
        {
            if (index <= p_dyn_alloc->end_index[loop])
            {
                start_data_addr = p_dyn_alloc->dynamic_mem_hw_data_base[p_dyn_alloc->block_id[loop]][addr_offset];
                break;
            }
            loop++;
        }while(loop < p_dyn_alloc->block_num);


       /* check if the index num exceed the max index num of the tbl */
       if(start_data_addr == 0)
       {
           DRV_DBG_INFO("\nERROR! Index-0x%x exceeds the max_index 0x%x! TblID: %d, Name:%s\n",
                        index, TABLE_MAX_INDEX(lchip, tbl_id) , tbl_id, TABLE_NAME(lchip, tbl_id));
           return DRV_E_INVALID_INDEX;
       }

       start_data_addr +=  ((index - p_dyn_alloc->start_index[loop]) / p_dyn_alloc->unit_num) * TABLE_ENTRY_OFFSET(lchip, tbl_id);

#if (1 == SDK_WORK_PLATFORM)
       drv_usw_table_get_dyn_hw_addr(lchip, tbl_id, index, &start_data_addr);
       start_data_addr += p_dyn_alloc->unit_size * (index % p_dyn_alloc->unit_num);
       ret = drv_usw_chip_write_sram_entry2(lchip, ((uint64)oper_bmp << DRV_BITS_PER_WORD) | start_data_addr, data, TABLE_ENTRY_SIZE(lchip, tbl_id));
#else
       ldev = DRV_MAP_LDEV(lchip);
       addr_offset = (index % p_dyn_alloc->unit_num) * (p_dyn_alloc->unit_size >> 2);
       loop = (TABLE_ENTRY_SIZE(lchip, tbl_id) >> 2);

       do
       {
           buf[(addr_offset << 1) + (count << 1)] = 0xFFFFFFFF;
           buf[(addr_offset << 1) + (count << 1) + 1] = data[count];
           count++;
       } while (--loop);
        start_data_addr += 2;

        DRV_ENTRY_LOCK(lchip);
        ret  = p_drv_master[lchip]->drv_chip_write_ext(ldev, ((uint64)oper_bmp << DRV_BITS_PER_WORD)|start_data_addr, (p_dyn_alloc->mem_size>>1),  buf);
        DRV_ENTRY_UNLOCK(lchip);
        ret = ret?DRV_E_CMD_NOT_DONE:ret;
#endif
}
#endif

#if (SDB_DISABLE != SDB_MODE)
    if (!ret && g_sdb_master[lchip] && g_sdb_master[lchip]->sdb_en)
    {
        ret = DRV_MCHIP_SDB_API(lchip)->drv_sdb_write_api(lchip, tbl_id, index, data, p_dyn_alloc->unit_size, oper_bmp);
    }
 #endif
    return ret;
}
/**
 @brief The function write table data to a sram memory location
  (the fast API interface:  all dynamic table which do not need mask write
*/
int32
drv_usw_chip_dyn_tbl_write2(uint8 lchip, uint32 index, uint32 cmd, uint8 oper_bmp, uint32* data)
{
    dynamic_mem_allocate_info_t* p_dyn_alloc = NULL;
    int32 ret = DRV_E_NONE;
    uint32 tbl_id = 0;
#if (SDB_MEM_MODEL != SDB_MODE)
#if (0 == SDK_WORK_PLATFORM)
    uint8   ldev = 0;
    uint8   done = 0;
#endif
    uint32 start_data_addr = 0;
    uint8   loop = 0;
    uint8   addr_offset = 0;
    uint8   unit_num = 0; 
#endif

#ifdef WARMBOOT
   if(p_drv_master[lchip]->wb_status == DRV_WB_STATUS_RELOADING)
    {
        return DRV_E_NONE;
    }
#endif

    tbl_id = DRV_IOC_MEMID(cmd);
    p_dyn_alloc = (dynamic_mem_allocate_info_t*)&(DYNAMIC_EXT_INFO_PTR(lchip, tbl_id)->dynamic_mem_allocate_info);
#if (SDB_MEM_MODEL != SDB_MODE)
{
#if (1 == SDK_WORK_PLATFORM)
    addr_offset += TABLE_ADDR_NUM(lchip, tbl_id);
#endif

    do
    {
        if (index <= p_dyn_alloc->end_index[loop])
        {
            start_data_addr = p_dyn_alloc->dynamic_mem_hw_data_base[p_dyn_alloc->block_id[loop]][addr_offset];
            break;
        }
        loop++;
    }while( loop < p_dyn_alloc->block_num);

    /* check if the index num exceed the max index num of the tbl */
    if(start_data_addr == 0)
    {
        DRV_DBG_INFO("\nERROR! Index-0x%x exceeds the max_index 0x%x! TblID: %d, Name:%s\n",
                     index, TABLE_MAX_INDEX(lchip, tbl_id) , tbl_id, TABLE_NAME(lchip, tbl_id));
        return DRV_E_INVALID_INDEX;
    }
    
    unit_num = p_dyn_alloc->unit_num;
    start_data_addr +=  ((index - p_dyn_alloc->start_index[loop]) / unit_num) * TABLE_ENTRY_OFFSET(lchip, tbl_id);

   if(unit_num != 1)
   {
#if (1 == SDK_WORK_PLATFORM)
       drv_usw_table_get_dyn_hw_addr(lchip, tbl_id, index, &start_data_addr);
       start_data_addr += p_dyn_alloc->unit_size * (index % unit_num);
       ret = drv_usw_chip_write_sram_entry2(lchip, ((uint64)oper_bmp << DRV_BITS_PER_WORD) | start_data_addr, data, TABLE_ENTRY_SIZE(lchip, tbl_id));
#else
        {
            /* read-modify-write */
            uint32 buf[64] = {0};
            uint8 count = 0;

            /* dyn tbl all support burst */
            start_data_addr += 0x1;
            ldev = DRV_MAP_LDEV(lchip);

            DRV_SUP1_ENTRY_LOCK(lchip);
            done = !p_drv_master[lchip]->drv_chip_read_ext(ldev, ((uint64)oper_bmp << DRV_BITS_PER_WORD) | start_data_addr, (p_dyn_alloc->mem_size>>2), buf, 0, (p_dyn_alloc->mem_size>>2));
            DRV_SUP1_ENTRY_UNLOCK(lchip);

            ret = !done?DRV_E_CMD_NOT_DONE:ret;

            addr_offset = (index % unit_num) * (p_dyn_alloc->unit_size>>2);
            loop = (TABLE_ENTRY_SIZE(lchip, tbl_id)>>2);
            do
            {
                buf[addr_offset + count] = data[count];
                count++;
            } while (--loop);
            DRV_ENTRY_LOCK(lchip);
            done  = !p_drv_master[lchip]->drv_chip_write_ext(ldev, ((uint64)oper_bmp << DRV_BITS_PER_WORD)|start_data_addr, (p_dyn_alloc->mem_size>>2), buf);
            DRV_ENTRY_UNLOCK(lchip);
            ret = !done?DRV_E_CMD_NOT_DONE:ret;
        }
#endif
    }
    else
    {
#if (1 == SDK_WORK_PLATFORM)
        ret  = drv_usw_chip_write_sram_entry2(lchip, (((uint64)oper_bmp << DRV_BITS_PER_WORD) | start_data_addr), data, TABLE_ENTRY_SIZE(lchip, tbl_id));
#else
        /* dyn tbl all support burst */
        start_data_addr += 0x1;
        ldev = DRV_MAP_LDEV(lchip);

        DRV_ENTRY_LOCK(lchip);
        done  = !p_drv_master[lchip]->drv_chip_write_ext(ldev, (((uint64)oper_bmp << DRV_BITS_PER_WORD) | start_data_addr), (TABLE_ENTRY_SIZE(lchip, tbl_id)>>2), data);
        DRV_ENTRY_UNLOCK(lchip);
        ret = !done?DRV_E_CMD_NOT_DONE:ret;
#endif
    }
}
#endif

#if (SDB_DISABLE != SDB_MODE)
    if (!ret && g_sdb_master[lchip] && g_sdb_master[lchip]->sdb_en)
    {
        ret = DRV_MCHIP_SDB_API(lchip)->drv_sdb_write_api(lchip, tbl_id, index, data, p_dyn_alloc->unit_size, oper_bmp);
    }
 #endif
    return ret;
}

extern int32
drv_usw_chip_sram_tbl_null(uint8 lchip, uint32 index, uint32 cmd, uint8 oper_bmp, uint32* data)
{
  return DRV_E_INVALID_TBL;
}

/**
 @brief The function read table data from a sram memory location
  the general API interface,:  all static table and all dynamic table
*/
int32
drv_usw_chip_sram_tbl_read(uint8 lchip, uint32 index, uint32 cmd, uint8 oper_bmp, uint32* data)
{
    uint32 start_data_addr = 0;
    uint8 burst_op = 0;
    uint32 tbl_id = 0;

    tbl_id = DRV_IOC_MEMID(cmd);
    if (TABLE_MAX_INDEX(lchip, tbl_id)<= index)
    {
        DRV_DBG_INFO("ERROR! (drv_usw_read_sram_tbl): chip-0x%x, tbl-0x%x, index-0x%x exceeds the max_index-0x%x.\n",
                    lchip, tbl_id, index, TABLE_MAX_INDEX(lchip, tbl_id));
        return DRV_E_INVALID_TBL;
    }

#if (SDB_DISABLE != SDB_MODE)
    if (DRV_READ_MEM_FROM_SER(tbl_id))
    {
        uint32 entry_offset = TABLE_INFO(lchip, tbl_id).tcam_mem ? TABLE_ENTRY_OFFSET(lchip, tbl_id) : TABLE_ENTRY_SIZE(lchip, tbl_id);
        sal_memcpy(data, (uint8*)drv_sdb_read(lchip, tbl_id, index, entry_offset, oper_bmp), TABLE_ENTRY_SIZE(lchip, tbl_id));
        return DRV_E_NONE;
    }
#endif

    drv_usw_table_get_hw_addr(lchip, tbl_id, index, &start_data_addr, 0);
    burst_op = !(TABLE_OP_TYPE(lchip, tbl_id)&Op_DisBurst) ;
    start_data_addr = start_data_addr + burst_op;
    return drv_usw_chip_read_sram_entry(lchip, start_data_addr, data, TABLE_ENTRY_SIZE(lchip, tbl_id));
}


/**
 @brief The function write table data to a sram memory location
 the general API interface,:  all static table and all dynamic table
*/
int32
drv_usw_chip_sram_tbl_write(uint8 lchip, uint32 index, uint32 cmd, uint8 oper_bmp, uint32* data)
{
    uint32 start_data_addr = 0;
    int32 ret = DRV_E_NONE;
    uint8 burst_op = 0;
    tables_info_t  * ptbl = NULL;
    uint32 tbl_id = 0;

#ifdef WARMBOOT
   if(p_drv_master[lchip]->wb_status == DRV_WB_STATUS_RELOADING)
    {
        return DRV_E_NONE;
    }
 #endif
    tbl_id = DRV_IOC_MEMID(cmd);
    ptbl = TABLE_INFO_PTR(lchip, tbl_id);
    /* check if the index num exceed the max index num of the tbl */
    if (TABLE_MAX_INDEX(lchip, tbl_id) <= index)
    {
        DRV_DBG_INFO("ERROR! (drv_usw_write_sram_tbl): chip-0x%x, tbl-0x%x, index-0x%x exceeds the max_index-0x%x.\n",
                    lchip, tbl_id, index, TABLE_MAX_INDEX(lchip, tbl_id));
        return DRV_E_INVALID_TBL;
    }

    burst_op = !(ptbl->optype & Op_DisBurst);

#if (SDK_WORK_PLATFORM == 0)
    /*static table/normal dynamic table (except parser table/80bit acl ad table) */
    if(!TABLE_EXT_INFO_PTR(lchip, tbl_id) || (TABLE_EXT_TYPE(lchip, tbl_id) == 0))  /*normal table*/
    {
         drv_usw_table_get_hw_addr(lchip, tbl_id, index, &start_data_addr, 0);
         start_data_addr = start_data_addr +burst_op;
          ret = drv_usw_chip_write_sram_entry(lchip, start_data_addr, data, TABLE_ENTRY_SIZE(lchip, tbl_id));
    }
   else  if(TABLE_EXT_TYPE(lchip, tbl_id) == 1)  /*parser table*/
    {
        uint8 tbl_offset;
        uint32 offset = 0;

        for(tbl_offset=0; tbl_offset < (sizeof(parser_tbl_id_list[0])>>2); tbl_offset++)
        {
            if(tbl_id == parser_tbl_id_list[0][tbl_offset])
            {
                break;
            }
        }

        if(tbl_offset == sizeof(parser_tbl_id_list[0])>>2)
        {
            DRV_DBG_INFO("ERROR! (drv_usw_write_sram_tbl): chip-0x%x, tbl-0x%x, index-0x%x is not an parser table\n",
                    lchip, tbl_id, index);
            return DRV_E_INVALID_TBL;
        }
       drv_usw_table_get_hw_addr(lchip, tbl_id, index, &start_data_addr, 0);
       start_data_addr = start_data_addr +burst_op;

        offset = index * TABLE_ENTRY_OFFSET(lchip, tbl_id) + burst_op;
        start_data_addr = TABLE_DATA_BASE(lchip, parser_tbl_id_list[2][tbl_offset], 0) + offset;

        DRV_IF_ERROR_RETURN(drv_usw_chip_write_sram_entry(lchip, start_data_addr, data, TABLE_ENTRY_SIZE(lchip, tbl_id)));
#if (SDB_DISABLE != SDB_MODE)
        drv_sdb_store(lchip, parser_tbl_id_list[2][tbl_offset], index, data, TABLE_ENTRY_SIZE(lchip, tbl_id), 0);
#endif
        start_data_addr = TABLE_DATA_BASE(lchip, parser_tbl_id_list[1][tbl_offset], 0) + offset;
        DRV_IF_ERROR_RETURN(drv_usw_chip_write_sram_entry(lchip, start_data_addr, data, TABLE_ENTRY_SIZE(lchip, tbl_id)));
#if (SDB_DISABLE != SDB_MODE)
        drv_sdb_store(lchip, parser_tbl_id_list[1][tbl_offset], index, data, TABLE_ENTRY_SIZE(lchip, tbl_id), 0);
#endif
        start_data_addr = TABLE_DATA_BASE(lchip, parser_tbl_id_list[0][tbl_offset], 0) + offset;
        DRV_IF_ERROR_RETURN(drv_usw_chip_write_sram_entry(lchip, start_data_addr, data, TABLE_ENTRY_SIZE(lchip, tbl_id)));
#if (SDB_DISABLE != SDB_MODE)
        drv_sdb_store(lchip, parser_tbl_id_list[0][tbl_offset], index, data, TABLE_ENTRY_SIZE(lchip, tbl_id), 0);
#endif

    }
    else if(TABLE_EXT_TYPE(lchip, tbl_id) == 2)  /*80bit acl ad table*/
    {
        uint32 data_rd[6] = {0};

         /*Process as 160bits*/
        drv_usw_table_get_hw_addr(lchip, tbl_id, (index&0xFFFFFFFE), &start_data_addr, 0);

        DRV_IF_ERROR_RETURN(drv_usw_chip_read_sram_entry(lchip, start_data_addr, data_rd, TABLE_ENTRY_SIZE(lchip, tbl_id)<<1));

        if (index&0x1)
        {
            /*high 80bits*/
           // sal_memcpy((uint8*)&data_rd[3], (uint8*)data, 12);
           data_rd[3] = data[0];
           data_rd[4] = data[1];
           data_rd[5] = data[2];
        }
        else
        {
            /*low 80bits*/
           // sal_memcpy((uint8*)&data_rd[0], (uint8*)data, 12);
           data_rd[0] = data[0];
           data_rd[1] = data[1];
           data_rd[2] = data[2];
        }

       ret = drv_usw_chip_write_sram_entry(lchip, start_data_addr, data_rd, TABLE_ENTRY_SIZE(lchip, tbl_id)<<1);

    }
#else
     drv_usw_table_get_hw_addr(lchip, tbl_id, index, &start_data_addr, 0);
     start_data_addr = start_data_addr +burst_op;
     ret = drv_usw_chip_write_sram_entry(lchip, start_data_addr, data, TABLE_ENTRY_SIZE(lchip, tbl_id));
 #endif

#if (SDB_DISABLE != SDB_MODE)
{
    uint32 entry_offset = TABLE_INFO(lchip, tbl_id).tcam_mem ? TABLE_ENTRY_OFFSET(lchip, tbl_id) : TABLE_ENTRY_SIZE(lchip, tbl_id);
    if(ret)   return ret;
    drv_sdb_store(lchip, tbl_id, index, data, entry_offset, 0);
}
#endif

    return ret;
}

/**
 @brief The function read table data from a sram memory location
  the fast API interface:  all dynamic table (except 80 bit acl AD table)
*/
int32
drv_usw_chip_dyn_tbl_read(uint8 lchip, uint32 index, uint32 cmd,  uint8 oper_bmp, uint32* data)
{
    uint32 start_data_addr = 0;
     uint8 i = 0;
    uint32 entry_offset = 0;
    uint32 tbl_id = 0;

    tbl_id = DRV_IOC_MEMID(cmd);
    if (TABLE_MAX_INDEX(lchip, tbl_id)<= index)
    {
        DRV_DBG_INFO("ERROR! (drv_usw_read_sram_tbl): chip-0x%x, tbl-0x%x, index-0x%x exceeds the max_index-0x%x.\n",
                    lchip, tbl_id, index, TABLE_MAX_INDEX(lchip, tbl_id));
        return DRV_E_INVALID_TBL;
    }
    entry_offset = TABLE_ENTRY_OFFSET(lchip, tbl_id);
#if (SDB_DISABLE != SDB_MODE)
    if (DRV_READ_MEM_FROM_SER(tbl_id))
    {
        sal_memcpy(data, (uint8*)drv_sdb_read(lchip, tbl_id, index, DYNAMIC_TABLE_UNIT_SIZE(lchip, tbl_id), oper_bmp), TABLE_ENTRY_SIZE(lchip, tbl_id));

        //drv_memcpy((uint32*)data,(uint32*)drv_sdb_read(lchip, tbl_id, index, entry_offset),TABLE_ENTRY_SIZE(lchip, tbl_id)>>2);
        return DRV_E_NONE;
    }
#endif

    do
    {
        if (index <= DYNAMIC_TABLE_END(lchip, tbl_id, i))
        {
            start_data_addr = DYNAMIC_DATA_BASE(lchip, tbl_id, DYNAMIC_TABLE_BLK_ID(lchip, tbl_id, i), 0);
            break;
        }
        i++;
    }while( i < DYNAMIC_TABLE_BLK_NUM(lchip, tbl_id) );

    start_data_addr  += (index - DYNAMIC_TABLE_START(lchip, tbl_id, i)) * entry_offset;
    start_data_addr  += (!(TABLE_OP_TYPE(lchip, tbl_id)&Op_DisBurst)) ;
    return drv_usw_chip_read_sram_entry(lchip, start_data_addr, data, TABLE_ENTRY_SIZE(lchip, tbl_id));
}

/**
 @brief The function write table data to a sram memory location
 the fast API interface:  all dynamic table (except 80 bit acl AD table)
*/
int32
drv_usw_chip_dyn_tbl_write(uint8 lchip, uint32 index, uint32 cmd,  uint8 oper_bmp, uint32* data)
{
    uint32 start_data_addr = 0;
    int32 ret = DRV_E_NONE;
    uint8 i = 0;
    uint32 tbl_id = 0;

#ifdef WARMBOOT
   if(p_drv_master[lchip]->wb_status == DRV_WB_STATUS_RELOADING)
    {
        return DRV_E_NONE;
    }
 #endif
    tbl_id = DRV_IOC_MEMID(cmd);
    /* check if the index num exceed the max index num of the tbl */
    if (TABLE_MAX_INDEX(lchip, tbl_id) <= index)
    {
        DRV_DBG_INFO("ERROR! (drv_usw_write_sram_tbl): chip-0x%x, tbl-0x%x, index-0x%x exceeds the max_index-0x%x.\n",
                    lchip, tbl_id, index, TABLE_MAX_INDEX(lchip, tbl_id));
        return DRV_E_INVALID_TBL;
    }

    do
    {
        if (index <= DYNAMIC_TABLE_END(lchip, tbl_id, i))
        {
            start_data_addr = DYNAMIC_DATA_BASE(lchip, tbl_id, DYNAMIC_TABLE_BLK_ID(lchip, tbl_id, i), 0);
            break;
        }
        i++;
    }while( i < DYNAMIC_TABLE_BLK_NUM(lchip, tbl_id) );

    start_data_addr  += (index - DYNAMIC_TABLE_START(lchip, tbl_id, i)) * TABLE_ENTRY_OFFSET(lchip, tbl_id);
    start_data_addr += ( !(TABLE_OP_TYPE(lchip, tbl_id) & Op_DisBurst));
    ret = drv_usw_chip_write_sram_entry(lchip, start_data_addr, data, TABLE_ENTRY_SIZE(lchip, tbl_id));
#if (SDB_DISABLE != SDB_MODE)
{
    if(ret)   return ret;
    drv_sdb_store(lchip, tbl_id, index, data, DYNAMIC_TABLE_UNIT_SIZE(lchip, tbl_id), 0);
}
#endif

    return ret;
}

int32
drv_usw_chip_lpm_tbl_write(uint8 lchip, uint32 index, uint32 cmd, uint8 oper_bmp, uint32* data)
{
    int32 ret = DRV_E_NONE;
    uint32 tbl_id = 0;
    uint32 buf[64] = {0};
#if (SDB_MEM_MODEL != SDB_MODE)
    tbl_entry_t* p_data = (tbl_entry_t*)data;
    int32   tmp = 0;
    uint32 length = 0;
    uint8 count = 0;
    uint8   ldev = 0;
    uint8   done = 0;
    uint32 start_data_addr = 0;
    uint8   loop = 0;
    dynamic_mem_allocate_info_t* p_dyn_alloc = NULL;
#endif

#ifdef WARMBOOT
   if(p_drv_master[lchip]->wb_status == DRV_WB_STATUS_RELOADING)
    {
        return DRV_E_NONE;
    }
 #endif
    tbl_id = DRV_IOC_MEMID(cmd);
#if (SDB_MEM_MODEL != SDB_MODE)
{
    p_dyn_alloc = (dynamic_mem_allocate_info_t*)&(DYNAMIC_EXT_INFO_PTR(lchip, tbl_id)->dynamic_mem_allocate_info);
    do
    {
        if (index <= p_dyn_alloc->end_index[loop])
        {
            start_data_addr = p_dyn_alloc->dynamic_mem_hw_data_base[p_dyn_alloc->block_id[loop]][0];
            break;
        }
        loop++;
    }while( loop < p_dyn_alloc->block_num);

   /* check if the index num exceed the max index num of the tbl */
   if(start_data_addr == 0)
   {
       DRV_DBG_INFO("\nERROR! Index-0x%x exceeds the max_index 0x%x! TblID: %d, Name:%s\n",
                    index, TABLE_MAX_INDEX(lchip, tbl_id) , tbl_id, TABLE_NAME(lchip, tbl_id));
       return DRV_E_INVALID_INDEX;
   }

    start_data_addr +=  (index - p_dyn_alloc->start_index[loop]) * TABLE_ENTRY_OFFSET(lchip, tbl_id);
    ldev = DRV_MAP_LDEV(lchip);
    loop = (TABLE_ENTRY_SIZE(lchip, tbl_id) >> 2);
    do
    {
        buf[(count << 1)] = p_data->mask_entry[count];
        buf[(count << 1) + 1] = p_data->data_entry[count];
        count++;
    } while (--loop);

    start_data_addr = (start_data_addr+2);
    tmp = (TABLE_ENTRY_SIZE(lchip, tbl_id) >> 1);
    loop = 0;
    
    DRV_ENTRY_LOCK(lchip);
    do
    {
        length = (tmp >= 16)? 16 : tmp;
        done  = !p_drv_master[lchip]->drv_chip_write(ldev, ((uint64)oper_bmp << DRV_BITS_PER_WORD)|start_data_addr, length,  buf + (loop<<4));
        start_data_addr += (length<<1);
        tmp -= 16;
        loop++;
    }while (done && (tmp > 0));
    DRV_ENTRY_UNLOCK(lchip);
    ret = !done?DRV_E_CMD_NOT_DONE:ret;
}
#endif

#if (SDB_DISABLE != SDB_MODE)
    if (!ret && g_sdb_master[lchip] && g_sdb_master[lchip]->sdb_en)
    {
        ret = DRV_MCHIP_SDB_API(lchip)->drv_sdb_write_api(lchip, tbl_id, ((1<<31) | index), buf, (TABLE_ENTRY_SIZE(lchip, tbl_id) <<1), oper_bmp);
    }
 #endif
    return ret;
}

/**
 @brief The function read table data from a sram memory location
   the fast API interface: all register ,only for drv_acc_api
*/
int32
drv_usw_chip_reg_read(uint8 lchip, uint32 tbl_id, uint32 index, uint8 oper_bmp, uint32* data)
{
    uint32 start_data_addr = 0;

    start_data_addr = TABLE_INFO(lchip, tbl_id).addrs[0] + 1;
    return drv_usw_chip_read_sram_entry(lchip, ((uint64)oper_bmp << DRV_BITS_PER_WORD) | start_data_addr, data, TABLE_ENTRY_SIZE(lchip, tbl_id));
}

/**
 @brief The function write table data to a sram memory location
  the fast API interface: all register ,only for drv_acc_api
*/
int32
drv_usw_chip_reg_write(uint8 lchip, uint32 tbl_id, uint32 index, uint8 oper_bmp, uint32* data)
{
    uint32 start_data_addr = 0;

    start_data_addr = TABLE_INFO(lchip, tbl_id).addrs[0] + 1;
  return drv_usw_chip_write_sram_entry(lchip, ((uint64)oper_bmp << DRV_BITS_PER_WORD) | start_data_addr, data, TABLE_ENTRY_SIZE(lchip, tbl_id));
}

#if (SDB_DISABLE != SDB_MODE)
/*refresh ram-id timestamp*/
static int32
_drv_usw_fresh_time_stamp(uint8 lchip, uint8 mem_id)
{
    TsEngineRefRc_m ts_ref_rc;
    uint32 cmd = DRV_IOR(TsEngineRefRc_t, DRV_ENTRY_FLAG);
    uint32 ts_s;
    uint32 ts_ns;
    uint64 total_ns = 0;
    uint32 ts_array[2] = {0};
    drv_sdb_t* p_sdb = g_sdb_master[lchip];

    DRV_IOCTL(lchip, 0, cmd, &ts_ref_rc);
    ts_s = GetTsEngineRefRc(V, rcSecond_f, &ts_ref_rc);
    ts_ns = GetTsEngineRefRc(V, rcNs_f, &ts_ref_rc);

    /*total ns is 60 bits in dma desc, so need to truncate*/
    total_ns = (ts_s*1000LL*1000LL*1000LL+ts_ns);
    ts_array[0] = (total_ns)&0xFFFFFFFF;
    ts_array[1] = (total_ns>>32)&0x3FFFFFFF;

    p_sdb->dma_scan_timestamp[mem_id][0] = ts_array[0];
    p_sdb->dma_scan_timestamp[mem_id][1] = (ts_array[1])&0X3FFFFFFF;

    return DRV_E_NONE;
}
#endif

#define __DRV_TCAM__

#if defined(EMULATION_ENV) && !defined(EMULATOR_ENV)
#define DRV_SER_TCAM_SCAN_EN(lchip) (NULL != p_drv_master[lchip]->p_ser_master && \
                                     drv_ser_get_tcam_scan_enable(lchip))
#else
#define DRV_SER_TCAM_SCAN_EN(lchip) (NULL != p_drv_master[lchip]->p_ser_master && \
                                     NULL != g_sdb_master[lchip] && \
                                     drv_ser_get_tcam_scan_enable(lchip))
#endif
#define DRV_SER_SET_HASH_BMP(lchip, ...)    \
    if (DRV_FROM_TMM(lchip) && DRV_SER_TCAM_SCAN_EN(lchip))\
    {\
        drv_ser_set_entry_bitmap(lchip, ##__VA_ARGS__);\
    }


int32
drv_usw_lpm_tcam_init_blknum(uint8 lchip)
{
    uint8 type = 0;
    uint32 blk_entry[3] = {0};
    uint32 entry_num_in_blk2[2] = {0};

    if (p_drv_master[lchip]->dev_type >= DRV_TSINGMA_MX)
    {
        blk_entry[0] = DRV_MEM_INFO(lchip, DRV_FTM_LPM_TCAM_KEY0).entry_num + \
                         DRV_MEM_INFO(lchip, DRV_FTM_LPM_TCAM_KEY1).entry_num;
        blk_entry[1] = DRV_MEM_INFO(lchip, DRV_FTM_LPM_TCAM_KEY2).entry_num + \
                         DRV_MEM_INFO(lchip, DRV_FTM_LPM_TCAM_KEY3).entry_num;
        blk_entry[2] = DRV_MEM_INFO(lchip, DRV_FTM_LPM_TCAM_KEY4).entry_num + \
                         DRV_MEM_INFO(lchip, DRV_FTM_LPM_TCAM_KEY5).entry_num;
        entry_num_in_blk2[0] = DRV_MEM_INFO(lchip, DRV_FTM_LPM_TCAM_KEY4).entry_num;
        entry_num_in_blk2[1] = DRV_MEM_INFO(lchip, DRV_FTM_LPM_TCAM_KEY5).entry_num;
    }
    else
    {
        blk_entry[0] = DRV_MEM_INFO(lchip, DRV_FTM_LPM_TCAM_KEY0).entry_num + \
                         DRV_MEM_INFO(lchip, DRV_FTM_LPM_TCAM_KEY1).entry_num + \
                         DRV_MEM_INFO(lchip, DRV_FTM_LPM_TCAM_KEY2).entry_num + \
                         DRV_MEM_INFO(lchip, DRV_FTM_LPM_TCAM_KEY3).entry_num ;
        blk_entry[1] = DRV_MEM_INFO(lchip, DRV_FTM_LPM_TCAM_KEY4).entry_num + \
                         DRV_MEM_INFO(lchip, DRV_FTM_LPM_TCAM_KEY5).entry_num + \
                         DRV_MEM_INFO(lchip, DRV_FTM_LPM_TCAM_KEY6).entry_num + \
                         DRV_MEM_INFO(lchip, DRV_FTM_LPM_TCAM_KEY7).entry_num ;
        blk_entry[2] = DRV_MEM_INFO(lchip, DRV_FTM_LPM_TCAM_KEY8).entry_num + \
                         DRV_MEM_INFO(lchip, DRV_FTM_LPM_TCAM_KEY9).entry_num + \
                         DRV_MEM_INFO(lchip, DRV_FTM_LPM_TCAM_KEY10).entry_num + \
                         DRV_MEM_INFO(lchip, DRV_FTM_LPM_TCAM_KEY11).entry_num ;


        entry_num_in_blk2[0] = DRV_MEM_INFO(lchip, DRV_FTM_LPM_TCAM_KEY8).entry_num + \
                                    DRV_MEM_INFO(lchip, DRV_FTM_LPM_TCAM_KEY9).entry_num;
        entry_num_in_blk2[1] = DRV_MEM_INFO(lchip, DRV_FTM_LPM_TCAM_KEY10).entry_num + \
                                    DRV_MEM_INFO(lchip, DRV_FTM_LPM_TCAM_KEY11).entry_num;
    }


    /*init lpm type 0, not care public or ipsa*/
    type = 0;
    p_drv_master[lchip]->lpm_block[type][0].block_id = 0;
    p_drv_master[lchip]->lpm_block[type][0].max_index = blk_entry[0];

    p_drv_master[lchip]->lpm_block[type][1].block_id = 1;
    p_drv_master[lchip]->lpm_block[type][1].max_index = blk_entry[0] + blk_entry[1];

    p_drv_master[lchip]->lpm_block[type][2].block_id = 2;
    p_drv_master[lchip]->lpm_block[type][2].max_index = blk_entry[0] + blk_entry[1] + blk_entry[2];

    /*init lpm type 1, public or ipda*/
    type = 1;
    p_drv_master[lchip]->lpm_block[type][0].block_id = 0;
    p_drv_master[lchip]->lpm_block[type][0].max_index =  blk_entry[0];

    p_drv_master[lchip]->lpm_block[type][1].block_id = 2;
    p_drv_master[lchip]->lpm_block[type][1].max_index =  blk_entry[0] + entry_num_in_blk2[0] ;

    /*init lpm type 2, private or ipsa*/
    type = 2;
    p_drv_master[lchip]->lpm_block[type][0].block_id = 1;
    p_drv_master[lchip]->lpm_block[type][0].max_index = blk_entry[1];

    p_drv_master[lchip]->lpm_block[type][1].block_id = 2;
    p_drv_master[lchip]->lpm_block[type][1].max_index = blk_entry[1] + entry_num_in_blk2[1];
    p_drv_master[lchip]->lpm_block[type][1].offset  =   entry_num_in_blk2[0];

    return DRV_E_NONE;
}

STATIC int32
drv_usw_lpm_tcam_get_blknum_index(uint8 lchip, tbls_id_t tbl_id, uint32 index, uint32 *blknum, uint32 *local_idx)
{
    uint8 type = TCAM_EXT_INFO_PTR(lchip, tbl_id)->lpm_type;

    if (index < p_drv_master[lchip]->lpm_block[type][0].max_index)
    {
        *blknum = p_drv_master[lchip]->lpm_block[type][0].block_id;
        *local_idx = index;
    }
    else if(index < p_drv_master[lchip]->lpm_block[type][1].max_index)
    {
        *blknum = p_drv_master[lchip]->lpm_block[type][1].block_id;
        *local_idx = index - p_drv_master[lchip]->lpm_block[type][0].max_index +  p_drv_master[lchip]->lpm_block[type][1].offset;
    }
    else
    {
        *blknum = p_drv_master[lchip]->lpm_block[type][2].block_id;
        *local_idx = index - p_drv_master[lchip]->lpm_block[type][1].max_index  + p_drv_master[lchip]->lpm_block[type][2].offset;
    }
    *local_idx = p_drv_master[lchip]->lpm_index_map[*blknum] ? p_drv_master[lchip]->lpm_index_map[*blknum][*local_idx] : *local_idx;
    return DRV_E_NONE;
}

STATIC int32
drv_tmg_lpm_tcam_get_blknum_index(uint8 lchip, tbls_id_t tbl_id, uint32 index, uint32 *blknum, uint32 *local_idx)
{
    uint8 type = TCAM_EXT_INFO_PTR(lchip, tbl_id)->lpm_type;
    if (index < p_drv_master[lchip]->lpm_block[type][0].max_index)
    {
        *blknum = p_drv_master[lchip]->lpm_block[type][0].block_id;
        *local_idx = index;
    }
    else if(index < p_drv_master[lchip]->lpm_block[type][1].max_index)
    {
        *blknum = p_drv_master[lchip]->lpm_block[type][1].block_id;
        *local_idx = index - p_drv_master[lchip]->lpm_block[type][0].max_index +  p_drv_master[lchip]->lpm_block[type][1].offset;
    }
    else
    {
        *blknum = p_drv_master[lchip]->lpm_block[type][2].block_id;
        *local_idx = index - p_drv_master[lchip]->lpm_block[type][1].max_index  + p_drv_master[lchip]->lpm_block[type][2].offset;
    }
    *local_idx = p_drv_master[lchip]->lpm_index_map[*blknum] ? p_drv_master[lchip]->lpm_index_map[*blknum][*local_idx] : *local_idx;
#ifdef EMULATION_ENV
    if (*local_idx >=16)
    {
        *local_idx += (2048 - 16);
    }
#endif
    return DRV_E_NONE;
}
int32 
drv_ioctl_read_tcam(uint8 lchip, drv_ioctl_param_t* p_ioctl_param)
{
    drv_io_tcam_db_t* p_db = NULL;
    uint8* ds = (uint8*)p_ioctl_param->p_value;
#if (SDB_DISABLE != SDB_MODE || 1 == MCHIP_SIM)
    uint8* p_ds = NULL;
#endif
    int32 ret = DRV_E_NONE;
    uint32 tbl_id = p_ioctl_param->tbl_id;
    uint32 hw_idx = 0;
    uint32 index = p_ioctl_param->index;
    uint8 entry_idx = 0;
    uint8 entry_num_each_idx = p_ioctl_param->entry_len;
    uint8 oper_bmp = p_ioctl_param->op_bmp;
    uint32 blknum = 0;
#if  (0 == SDK_WORK_PLATFORM)
    uint8 entry_size_per_index = 0;
#endif

    if (TABLE_MAX_INDEX(lchip, tbl_id) <= index)
    {
        DRV_DBG_INFO("ERROR! (drv_usw_chip_tcam_tbl_read): chip-0x%x, tbl-0x%x, index-0x%x exceeds the max_index-0x%x.\n",
                    lchip, tbl_id, index, TABLE_MAX_INDEX(lchip, tbl_id));
        return DRV_E_INVALID_TBL;
    }

    oper_bmp &= p_drv_master[lchip]->oper_mask[TABLE_ENTRY_TYPE(lchip, tbl_id)];
    p_db = &p_drv_master[lchip]->drv_io_tcam_db[TCAM_KEY_DRV_TYPE(lchip, tbl_id)];
    p_db->drv_tcam_get_block_info(lchip, tbl_id, index, &blknum, &index);
    hw_idx = ((blknum << p_db->blk_shift) | index); 

    DRV_TCAM_LOCK(lchip);

#if (SDB_DISABLE != SDB_MODE)
    if (DRV_READ_MEM_FROM_SER(p_db->tcam_mem_tbl_id))
    {
        do
        {
            p_ds = (uint8*)drv_sdb_read(lchip, p_db->tcam_mem_tbl_id, hw_idx, TABLE_ENTRY_OFFSET(lchip, p_db->tcam_mem_tbl_id), oper_bmp);
            sal_memcpy(&ds[entry_idx*TABLE_ENTRY_OFFSET(lchip, p_db->tcam_mem_tbl_id)], p_ds,TABLE_ENTRY_OFFSET(lchip, p_db->tcam_mem_tbl_id));
            p_ds += TABLE_ENTRY_OFFSET(lchip, p_db->tcam_mem_tbl_id);
            entry_idx++;
            hw_idx += (1 << p_db->blk_shift);
        }while(entry_idx <  entry_num_each_idx);
    }
   else
 #endif
    {
        uint32 start_data_addr = 0;
        uint8 burst_op = 0;

        burst_op = !(TABLE_OP_TYPE(lchip, tbl_id)&Op_DisBurst) && p_drv_master[lchip]->burst_en;
        start_data_addr = TABLE_INFO(lchip, p_db->tcam_mem_tbl_id).addrs[0] + (hw_idx * (p_db->hw_words << 2));
#if (1 == SDK_WORK_PLATFORM)
        start_data_addr = TABLE_INFO(lchip, p_db->tcam_mem_tbl_id).addrs[1] + (hw_idx * (p_db->hw_words << 2));
#endif
        start_data_addr += burst_op;
        do
        {
            ret = ret ? ret: drv_usw_chip_read_sram_entry(lchip, ((uint64)oper_bmp << DRV_BITS_PER_WORD) | start_data_addr, (uint32*)ds,  TABLE_ENTRY_SIZE(lchip, p_db->tcam_mem_tbl_id));
#if  (0 == SDK_WORK_PLATFORM)
            entry_size_per_index = (TABLE_ENTRY_SIZE(lchip, p_db->tcam_mem_tbl_id) - 4)>>1;
            DRV_SDB_TCAM_XY2DM(((uint32*)ds), entry_size_per_index);
#endif
            ds += TABLE_ENTRY_OFFSET(lchip, p_db->tcam_mem_tbl_id);
            entry_idx++;
            start_data_addr += ((p_db->hw_words << 2) << p_db->blk_shift);
        }while(entry_idx < entry_num_each_idx);
    }

    DRV_TCAM_UNLOCK(lchip);
    return ret;
}

int32 
drv_ioctl_write_tcam(uint8 lchip, drv_ioctl_param_t* p_ioctl_param)
{
    drv_io_tcam_db_t* p_db = NULL;
    int32 ret = 0;
    uint32 tbl_id = p_ioctl_param->tbl_id;
    uint32 hw_idx = 0;
    uint32 start_data_addr = 0;
    uint32 index = p_ioctl_param->index;
    uint8 oper_bmp = p_ioctl_param->op_bmp;
    uint8* ds = NULL;
    uint8 entry_idx = 0;
    uint8 entry_num_each_idx = p_ioctl_param->entry_len;
    uint32 blknum = 0;
    uint8 burst_op =  !(TABLE_OP_TYPE(lchip, tbl_id)&Op_DisBurst) && p_drv_master[lchip]->burst_en;

#ifdef WARMBOOT
   if(p_drv_master[lchip]->wb_status == DRV_WB_STATUS_RELOADING)
    {
        return DRV_E_NONE;
    }
 #endif
    if (TABLE_MAX_INDEX(lchip, tbl_id) <= index)
    {
        DRV_DBG_INFO("ERROR! (drv_usw_chip_tcam_tbl_read): chip-0x%x, tbl-0x%x, index-0x%x exceeds the max_index-0x%x.\n",
                    lchip, tbl_id, index, TABLE_MAX_INDEX(lchip, tbl_id));
        return DRV_E_INVALID_TBL;
    }

    ds = (uint8*)p_ioctl_param->p_value;
    oper_bmp &= p_drv_master[lchip]->oper_mask[TABLE_ENTRY_TYPE(lchip, tbl_id)];
    p_db = &p_drv_master[lchip]->drv_io_tcam_db[TCAM_KEY_DRV_TYPE(lchip, tbl_id)];
    p_db->drv_tcam_get_block_info(lchip, tbl_id, index, &blknum, &index);
    hw_idx = ((blknum << p_db->blk_shift) | index);

    DRV_TCAM_LOCK(lchip);
    do
    {    
        start_data_addr = TABLE_INFO(lchip, p_db->tcam_mem_tbl_id).addrs[0] + (hw_idx * (p_db->hw_words << 2));
#if (1 == SDK_WORK_PLATFORM)
        start_data_addr = TABLE_INFO(lchip, p_db->tcam_mem_tbl_id).addrs[1] + (hw_idx * (p_db->hw_words << 2));
#endif    
        start_data_addr = start_data_addr + burst_op;
        ret  = drv_usw_chip_write_sram_entry(lchip, ((uint64)oper_bmp << DRV_BITS_PER_WORD) | start_data_addr, (uint32*)ds, TABLE_ENTRY_SIZE(lchip, p_db->tcam_mem_tbl_id));
#if (SDB_DISABLE != SDB_MODE)
        if (!ret && g_sdb_master[lchip] && g_sdb_master[lchip]->sdb_en)
        {
            DRV_MCHIP_SDB_API(lchip)->drv_sdb_write_api(lchip, p_db->tcam_mem_tbl_id, hw_idx, ds, TABLE_ENTRY_OFFSET(lchip, p_db->tcam_mem_tbl_id), oper_bmp);
        }
#endif
        /* set the bit value which corresponds to this entry equals to zero in the bitmap */
#if ((defined(EMULATION_ENV) && !defined(EMULATOR_ENV)))
        DRV_SER_SET_HASH_BMP(lchip, p_db->mem_id + blknum, index, FALSE, 1, ds);
#else
{
        uint8 tcam_hash_en = 0;
        tcam_hash_en = p_drv_master[lchip]->p_ser_master && ((drv_ser_master_t*)p_drv_master[lchip]->p_ser_master)->tcam_scan_en;

        if (tcam_hash_en)
        {
            drv_ser_set_entry_bitmap(lchip, p_db->mem_id + blknum, index, oper_bmp);
        }
}
#endif
        ds += (TABLE_ENTRY_OFFSET(lchip, p_db->tcam_mem_tbl_id));
        hw_idx += (1 << p_db->blk_shift);
        entry_idx++;
        blknum++;
    }while(entry_idx < entry_num_each_idx);

    DRV_TCAM_UNLOCK(lchip);
    return ret;
}

int32 
drv_ioctl_remove_tcam(uint8 lchip, drv_ioctl_param_t* p_ioctl_param)
{
    drv_io_tcam_db_t* p_db = NULL;
    uint32 tbl_id = p_ioctl_param->tbl_id;
    uint32 hw_idx = 0;
    uint32 index = p_ioctl_param->index;
    uint8 entry_idx = 0;
    uint8 oper_bmp = p_ioctl_param->op_bmp;
    uint8 entry_num_each_idx = p_ioctl_param->entry_len;
    uint32 blknum = 0;
    uint8 ds[DRV_DS_SIZE] = {0};
    uint8 burst_op = !(TABLE_OP_TYPE(lchip, tbl_id)&Op_DisBurst) && p_drv_master[lchip]->burst_en;
    uint32 start_data_addr = 0;

    if (TABLE_MAX_INDEX(lchip, tbl_id) <= index)
    {
        DRV_DBG_INFO("ERROR! (drv_usw_chip_tcam_tbl_read): chip-0x%x, tbl-0x%x, index-0x%x exceeds the max_index-0x%x.\n",
                    lchip, tbl_id, index, TABLE_MAX_INDEX(lchip, tbl_id));
        return DRV_E_INVALID_TBL;
    }

    oper_bmp &= p_drv_master[lchip]->oper_mask[TABLE_ENTRY_TYPE(lchip, tbl_id)];
    p_db = &p_drv_master[lchip]->drv_io_tcam_db[TCAM_KEY_DRV_TYPE(lchip, tbl_id)];
    p_db->drv_tcam_get_block_info(lchip, tbl_id, index, &blknum, &index);
    hw_idx = ((blknum << p_db->blk_shift) | index);

    DRV_TCAM_LOCK(lchip);
    do
    {
        start_data_addr = TABLE_INFO(lchip, p_db->tcam_mem_tbl_id).addrs[0] + (hw_idx * (p_db->hw_words << 2));
#if (1 == SDK_WORK_PLATFORM)
        start_data_addr = TABLE_INFO(lchip, p_db->tcam_mem_tbl_id).addrs[1] + (hw_idx * (p_db->hw_words << 2));
#endif
        start_data_addr = start_data_addr + burst_op;
        DRV_IF_ERROR_RETURN_WITH_UNLOCK(drv_usw_chip_write_sram_entry(lchip, ((uint64)oper_bmp << DRV_BITS_PER_WORD) | start_data_addr, (uint32*)ds, TABLE_ENTRY_SIZE(lchip, p_db->tcam_mem_tbl_id)), p_drv_master[lchip]->p_tcam_write_mutex);

#if (SDB_DISABLE != SDB_MODE)
        if (g_sdb_master[lchip] && g_sdb_master[lchip]->sdb_en)
        {
            DRV_MCHIP_SDB_API(lchip)->drv_sdb_write_api(lchip, p_db->tcam_mem_tbl_id, hw_idx, ds, TABLE_ENTRY_OFFSET(lchip, p_db->tcam_mem_tbl_id), oper_bmp);
        }
#endif
        /* set the bit value which corresponds to this entry equals to zero in the bitmap */
#if ((defined(EMULATION_ENV) && !defined(EMULATOR_ENV)))
        DRV_SER_SET_HASH_BMP(lchip, p_db->mem_id + blknum, index, FALSE, 1, ds);
#else
{
        uint8 tcam_hash_en = 0;
        tcam_hash_en = p_drv_master[lchip]->p_ser_master && ((drv_ser_master_t*)p_drv_master[lchip]->p_ser_master)->tcam_scan_en;

        if (tcam_hash_en)
        {
            drv_ser_set_entry_bitmap(lchip, p_db->mem_id + blknum, index, oper_bmp);
        }
}
#endif
        entry_idx++;
        blknum++;
        hw_idx += (1 << p_db->blk_shift);
    }while(entry_idx < entry_num_each_idx);

    DRV_TCAM_UNLOCK(lchip);
    return DRV_E_NONE;
}

inline static int32
_drv_ioctl_move_ad(uint8 lchip, drv_ioctl_param_t* p_src_param, drv_ioctl_param_t* p_dst_param)
{
    uint32 src_ad_tbl = p_src_param->ad_tbl_id;
    uint32 dst_ad_tbl = p_dst_param->ad_tbl_id;
    uint32 data[16] = {0};
    int32 ret = DRV_E_NONE;
    uint8 dst_oper_bmp = p_dst_param->op_bmp;
    uint8 src_oper_bmp = p_src_param->op_bmp;
#if (SDK_WORK_PLATFORM == 0)
    uint32* ds = NULL;
    uint32 start_data_addr = 0;
    uint8 burst_op = 0;
#endif

    dst_oper_bmp &= p_drv_master[lchip]->oper_mask[TABLE_ENTRY_TYPE(lchip, src_ad_tbl)];
    src_oper_bmp &= p_drv_master[lchip]->oper_mask[TABLE_ENTRY_TYPE(lchip, dst_ad_tbl)];

#if (SDK_WORK_PLATFORM == 1)
    ret = p_drv_master[lchip]->ioctl_cb[DRV_TBL_TYPE_NORMAL][DRV_IOC_READ](lchip, p_src_param->ad_index, (DRV_ENTRY_FLAG|((src_ad_tbl&DRV_IOC_MEMID_MASK)<<DRV_IOC_MEMID_SHIFT)), src_oper_bmp, data);
    ret = ret? ret: p_drv_master[lchip]->ioctl_cb[DRV_TBL_TYPE_NORMAL][DRV_IOC_WRITE](lchip, p_dst_param->ad_index, (DRV_ENTRY_FLAG|((dst_ad_tbl&DRV_IOC_MEMID_MASK)<<DRV_IOC_MEMID_SHIFT)), dst_oper_bmp, data);
    
    return ret;
#else
    burst_op = !(TABLE_OP_TYPE(lchip, dst_ad_tbl)&Op_DisBurst) && p_drv_master[lchip]->burst_en;
    /* get old ad data */
#if (SDB_DISABLE != SDB_MODE)
    if (DRV_READ_MEM_FROM_SER(src_ad_tbl))
    {
        ds = (uint32*)drv_sdb_read(lchip, src_ad_tbl, p_src_param->ad_index, TABLE_ENTRY_SIZE(lchip, src_ad_tbl), src_oper_bmp);
    }
    else
#endif
    {
        drv_usw_table_get_hw_addr(lchip, src_ad_tbl, p_src_param->ad_index, &start_data_addr, 0);
        start_data_addr = start_data_addr + burst_op;
        DRV_IF_ERROR_RETURN(drv_usw_chip_read_sram_entry(lchip, ((uint64)src_oper_bmp << DRV_BITS_PER_WORD) | start_data_addr, data, TABLE_ENTRY_SIZE(lchip, src_ad_tbl)));
        ds = data;
    }
    /* write old ad data to new idx */
    if(TABLE_EXT_TYPE(lchip, dst_ad_tbl) != 2)
    {
        drv_usw_table_get_hw_addr(lchip, dst_ad_tbl, p_dst_param->ad_index, &start_data_addr, 0);
        start_data_addr = start_data_addr +burst_op;
        ret = drv_usw_chip_write_sram_entry(lchip, ((uint64)dst_oper_bmp << DRV_BITS_PER_WORD) | start_data_addr, ds, TABLE_ENTRY_SIZE(lchip, dst_ad_tbl));
    }
    else
    {
         uint32 data_rd[6] = {0};
         
         drv_usw_table_get_hw_addr(lchip, dst_ad_tbl, (p_dst_param->ad_index&0xFFFFFFFE), &start_data_addr, 0);
         start_data_addr = start_data_addr + burst_op;
         DRV_IF_ERROR_RETURN(drv_usw_chip_read_sram_entry(lchip, ((uint64)dst_oper_bmp << DRV_BITS_PER_WORD) | start_data_addr, data_rd, TABLE_ENTRY_SIZE(lchip, dst_ad_tbl)<<1));
         if (p_dst_param->ad_index&0x1)
         {
             /*high 80bits*/
            data_rd[3] = ds[0];
            data_rd[4] = ds[1];
            data_rd[5] = ds[2];
         }
         else
         {
             /*low 80bits*/
            data_rd[0] = ds[0];
            data_rd[1] = ds[1];
            data_rd[2] = ds[2];
         }
         ret = drv_usw_chip_write_sram_entry(lchip, ((uint64)dst_oper_bmp << DRV_BITS_PER_WORD) | start_data_addr, data_rd, TABLE_ENTRY_SIZE(lchip, dst_ad_tbl)<<1);
    }

#if (SDB_DISABLE != SDB_MODE)
    {
        if(ret)   return ret;
        DRV_MCHIP_SDB_API(lchip)->drv_sdb_write_api(lchip, dst_ad_tbl, p_dst_param->ad_index, ds, TABLE_ENTRY_SIZE(lchip, dst_ad_tbl), dst_oper_bmp);
    }
#endif
#endif

    return ret;
}

inline static int32
_drv_ioctl_move_key(uint8 lchip, drv_ioctl_param_t* p_src_param, drv_ioctl_param_t* p_dst_param)
{
    drv_io_tcam_db_t* p_db = NULL;
    uint32 dst_tbl = p_dst_param->tbl_id;
    uint32 src_tbl = p_src_param->tbl_id;
    uint8 src_oper_bmp = p_src_param->op_bmp;
    uint8 dst_oper_bmp = p_dst_param->op_bmp;
    int32 ret = DRV_E_NONE;
    uint8 entry_idx = 0;
#if  (0 == SDK_WORK_PLATFORM)
    uint32* ds = NULL;
    uint32 data[16] = {0};
    uint32 start_data_addr = 0;
    uint32 dst_hw_idx = 0;
    uint32 src_hw_idx = 0;
    uint32 aligned_entry_size = 0;
    uint32 s_local_idx = 0;
    uint32 s_blknum = 0;
    uint32 blknum = 0;
    uint32 local_idx = 0;
    uint16 offset = 0;
    uint8 burst_op = 0;
    uint8 tcam_hash_en = 0;
    uint8 entry_size_per_index = 0;
    uint8 entry_num_each_idx = p_dst_param->entry_len;
#endif

    p_db = &p_drv_master[lchip]->drv_io_tcam_db[TCAM_KEY_DRV_TYPE(lchip, dst_tbl)];
    dst_oper_bmp &= p_drv_master[lchip]->oper_mask[TABLE_ENTRY_TYPE(lchip, src_tbl)];
    src_oper_bmp &= p_drv_master[lchip]->oper_mask[TABLE_ENTRY_TYPE(lchip, dst_tbl)];

#if  (0 == SDK_WORK_PLATFORM)
    entry_num_each_idx += (TCAM_KEY_SIZE(lchip, dst_tbl)/p_db->tbl_size -1);
    p_db->drv_tcam_get_block_info(lchip, src_tbl, p_src_param->index, &s_blknum, &s_local_idx);
    p_db->drv_tcam_get_block_info(lchip, dst_tbl, p_dst_param->index, &blknum, &local_idx);
    src_hw_idx = (s_blknum << p_db->blk_shift) | s_local_idx;
    dst_hw_idx = ((blknum << p_db->blk_shift) | local_idx);
    offset = (1 != p_dst_param->entry_len)? (1 << p_db->blk_shift): 1;
    aligned_entry_size = p_db->hw_words << 2;
#endif


#if (1 == SDK_WORK_PLATFORM)
{
    tbl_entry_t entry;
    uint32 p_value[24] = {0};
    uint32 p_mask[24] = {0};

    entry.data_entry = p_value;
    entry.mask_entry = p_mask;
    do
    {
        ret = ret ? ret: p_drv_master[lchip]->ioctl_cb[DRV_TBL_TYPE_TCAM][DRV_IOC_READ](lchip, p_src_param->index/(TCAM_KEY_SIZE(lchip, src_tbl)/p_db->tbl_size), (DRV_ENTRY_FLAG|((src_tbl&DRV_IOC_MEMID_MASK)<<DRV_IOC_MEMID_SHIFT)), src_oper_bmp, (uint32*)&entry);
        ret = ret ? ret: p_drv_master[lchip]->ioctl_cb[DRV_TBL_TYPE_TCAM][DRV_IOC_WRITE](lchip, p_dst_param->index/(TCAM_KEY_SIZE(lchip, dst_tbl)/p_db->tbl_size), ((dst_tbl&DRV_IOC_MEMID_MASK)<<DRV_IOC_MEMID_SHIFT), dst_oper_bmp, (uint32*)&entry);
        src_tbl++;
        dst_tbl++;
        entry_idx++;
    }while(entry_idx < p_dst_param->entry_len);

    return ret;
}
#else
    tcam_hash_en = p_drv_master[lchip]->p_ser_master && ((drv_ser_master_t*)p_drv_master[lchip]->p_ser_master)->tcam_scan_en;
    burst_op = !(TABLE_OP_TYPE(lchip, dst_tbl)&Op_DisBurst) && p_drv_master[lchip]->burst_en;
    do
    {
    /*  get old key data if get form hw need switch to data mask before write */
#if (SDB_DISABLE != SDB_MODE)
        if (DRV_READ_MEM_FROM_SER(p_db->tcam_mem_tbl_id))
        {
            ds = (uint32*)drv_sdb_read(lchip, p_db->tcam_mem_tbl_id, src_hw_idx, aligned_entry_size, src_oper_bmp);
        }
        else
#endif
        {
            start_data_addr = TABLE_INFO(lchip, p_db->tcam_mem_tbl_id).addrs[0] + (src_hw_idx * aligned_entry_size);
            start_data_addr += burst_op;
            ret = ret ? ret: drv_usw_chip_read_sram_entry(lchip, ((uint64)src_oper_bmp << DRV_BITS_PER_WORD) | start_data_addr, data,  TABLE_ENTRY_SIZE(lchip, p_db->tcam_mem_tbl_id));
            entry_size_per_index = (TABLE_ENTRY_SIZE(lchip, p_db->tcam_mem_tbl_id) - 4)>>1;
            DRV_SDB_TCAM_XY2DM(data, entry_size_per_index);
            ds = data;
        }
        /* write old key data to new idx */
        start_data_addr = TABLE_INFO(lchip, p_db->tcam_mem_tbl_id).addrs[0] + (dst_hw_idx * aligned_entry_size);
        start_data_addr = start_data_addr + burst_op;
        DRV_IF_ERROR_RETURN(drv_usw_chip_write_sram_entry(lchip, ((uint64)dst_oper_bmp << DRV_BITS_PER_WORD) | start_data_addr, ds, TABLE_ENTRY_SIZE(lchip, p_db->tcam_mem_tbl_id)));
#if (SDB_DISABLE != SDB_MODE)
        if ((p_drv_master[lchip]->dev_type < DRV_TSINGMA_MX) && tcam_hash_en)
        {
            _drv_usw_fresh_time_stamp(lchip, p_db->mem_id + blknum);
        }
        DRV_MCHIP_SDB_API(lchip)->drv_sdb_write_api(lchip, p_db->tcam_mem_tbl_id, dst_hw_idx, ds, TABLE_ENTRY_OFFSET(lchip, p_db->tcam_mem_tbl_id), dst_oper_bmp);
#endif
        /* set the bit value which corresponds to this entry equals to zero in the bitmap */
#if ((defined(EMULATION_ENV) && !defined(EMULATOR_ENV)))
        DRV_SER_SET_HASH_BMP(lchip, p_db->mem_id + blknum, local_idx, FALSE, 1, ds);
#else
        if ((p_drv_master[lchip]->dev_type >= DRV_TSINGMA_MX) && tcam_hash_en)
        {
            drv_ser_set_entry_bitmap(lchip, p_db->mem_id + blknum,  local_idx, dst_oper_bmp);
        }
#endif
        if (1 != p_dst_param->entry_len)
        {
            blknum++;
        }
        else
        {
            local_idx++;
        }
        entry_idx++;
        src_hw_idx += offset;
        dst_hw_idx += offset;
    }while(entry_idx < entry_num_each_idx);
#endif

    return ret;
}

inline static int32
_drv_ioctl_remove_key(uint8 lchip, drv_ioctl_param_t* p_src_param)
{
    drv_io_tcam_db_t* p_db = NULL;
    uint32 src_tbl = p_src_param->tbl_id;
    uint8 oper_bmp = p_src_param->op_bmp;
    uint8 entry_idx = 0;
#if (0 == SDK_WORK_PLATFORM)
    uint32 data[16] = {0};
    uint32 start_data_addr = 0;
    uint32 s_local_idx = 0;
    uint32 s_blknum = 0;
    uint32 src_hw_idx = 0;
    uint16 offset = 0;
    uint8 entry_num_each_idx = p_src_param->entry_len;
    uint8 burst_op = 0;
    uint8 tcam_hash_en = 0;
#endif

    p_db = &p_drv_master[lchip]->drv_io_tcam_db[TCAM_KEY_DRV_TYPE(lchip, src_tbl)];
    oper_bmp &= p_drv_master[lchip]->oper_mask[TABLE_ENTRY_TYPE(lchip, src_tbl)];
#if (0 == SDK_WORK_PLATFORM)
    entry_num_each_idx += (TCAM_KEY_SIZE(lchip, src_tbl)/p_db->tbl_size -1);
    p_db->drv_tcam_get_block_info(lchip, src_tbl, p_src_param->index, &s_blknum, &s_local_idx);
    tcam_hash_en = p_drv_master[lchip]->p_ser_master && ((drv_ser_master_t*)p_drv_master[lchip]->p_ser_master)->tcam_scan_en;
    src_hw_idx = (s_blknum << p_db->blk_shift) | s_local_idx;
    offset = (1 != p_src_param->entry_len)? (1 << p_db->blk_shift): 1;    
#endif


#if (1 == SDK_WORK_PLATFORM)
{
    tbl_entry_t entry;
    uint32 p_value[24] = {0};
    uint32 p_mask[24] = {0};
    entry.data_entry = p_value;
    entry.mask_entry = p_mask;
    do
    {
        DRV_IF_ERROR_RETURN(p_drv_master[lchip]->ioctl_cb[DRV_TBL_TYPE_TCAM][DRV_IOC_REMOVE](lchip, p_src_param->index/(TCAM_KEY_SIZE(lchip, src_tbl)/p_db->tbl_size), (DRV_ENTRY_FLAG|((src_tbl&DRV_IOC_MEMID_MASK)<<DRV_IOC_MEMID_SHIFT)), oper_bmp, (uint32*)&entry));
        src_tbl++;
        entry_idx++;
    }while(entry_idx <p_src_param->entry_len);

    return DRV_E_NONE;
}
#else
    burst_op = !(TABLE_OP_TYPE(lchip, src_tbl)&Op_DisBurst) && p_drv_master[lchip]->burst_en;
    do
    {
        start_data_addr = TABLE_INFO(lchip, p_db->tcam_mem_tbl_id).addrs[0] + (src_hw_idx * (p_db->hw_words << 2));
        start_data_addr = start_data_addr + burst_op;
        DRV_IF_ERROR_RETURN(drv_usw_chip_write_sram_entry(lchip, ((uint64)oper_bmp << DRV_BITS_PER_WORD) | start_data_addr, data, TABLE_ENTRY_SIZE(lchip, p_db->tcam_mem_tbl_id)));
#if (SDB_DISABLE != SDB_MODE)
        if ((p_drv_master[lchip]->dev_type < DRV_TSINGMA_MX) && tcam_hash_en)
        {
            _drv_usw_fresh_time_stamp(lchip, p_db->mem_id+s_blknum);
        }
        DRV_MCHIP_SDB_API(lchip)->drv_sdb_write_api(lchip, p_db->tcam_mem_tbl_id, src_hw_idx, data, TABLE_ENTRY_OFFSET(lchip, p_db->tcam_mem_tbl_id), oper_bmp);
#endif
        /* set the bit value which corresponds to this entry equals to zero in the bitmap */
#if ((defined(EMULATION_ENV) && !defined(EMULATOR_ENV)))
        DRV_SER_SET_HASH_BMP(lchip, p_db->mem_id + s_blknum, s_local_idx, FALSE, 1, data);
#else
        if ((p_drv_master[lchip]->dev_type >= DRV_TSINGMA_MX) && tcam_hash_en)
        {
            drv_ser_set_entry_bitmap(lchip, p_db->mem_id+s_blknum, s_local_idx, oper_bmp);
        }
#endif
        if (1 != p_src_param->entry_len)
        {
            s_blknum++;
        }
        else
        {
            s_local_idx++;
        }
        entry_idx++;
        src_hw_idx += offset;
    }while(entry_idx < entry_num_each_idx);
#endif
    return DRV_E_NONE;
}

int32 
drv_ioctl_move_tcam(uint8 lchip, drv_ioctl_param_t* p_src_param, drv_ioctl_param_t* p_dst_param)
{
    /* 1. move ad */
    DRV_IF_ERROR_RETURN(_drv_ioctl_move_ad(lchip, p_src_param, p_dst_param));
#if(SDK_WORK_PLATFORM == 0)
    DRV_TCAM_LOCK(lchip);
    /* 2. move tcam key */
    DRV_IF_ERROR_RETURN_WITH_UNLOCK(_drv_ioctl_move_key(lchip, p_src_param, p_dst_param), p_drv_master[lchip]->p_tcam_write_mutex);

    /* 3. delete old tcam key */
    DRV_IF_ERROR_RETURN_WITH_UNLOCK(_drv_ioctl_remove_key(lchip, p_src_param), p_drv_master[lchip]->p_tcam_write_mutex);

    DRV_TCAM_UNLOCK(lchip);
#else
    /* 2. move tcam key */
    DRV_IF_ERROR_RETURN(_drv_ioctl_move_key(lchip, p_src_param, p_dst_param));

    /* 3. delete old tcam key */
    DRV_IF_ERROR_RETURN(_drv_ioctl_remove_key(lchip, p_src_param));
#endif

    return DRV_E_NONE;
}

/**
 @brief read tcam interface (include operate model and real tcam)
*/
int32
drv_usw_chip_tcam_tbl_read(uint8 lchip, uint32 index, uint32 cmd, uint8 oper_bmp, uint32 *value)
{
    uint32 tbl_id = 0;
    uint8 entry_idx = 0;
    uint8 entry_num_each_idx = 0;
    uint32 *p_mask = NULL;
    uint8 tbl_words = 0;
    uint32 blknum = 0;
    uint32 local_idx = 0;
    int32 ret = DRV_E_NONE;
    uint8 loop = 0;
    drv_io_tcam_db_t* p_db = NULL;
    tbl_entry_t *entry = (tbl_entry_t *)value;
#if  (0 == SDK_WORK_PLATFORM)
    uint32 mask_tmp = 0;
#endif

     tbl_id = DRV_IOC_MEMID(cmd);
     if (TABLE_MAX_INDEX(lchip, tbl_id) <= index)
    {
        DRV_DBG_INFO("ERROR! (drv_usw_chip_tcam_tbl_read): chip-0x%x, tbl-0x%x, index-0x%x exceeds the max_index-0x%x.\n",
                    lchip, tbl_id, index, TABLE_MAX_INDEX(lchip, tbl_id));
        return DRV_E_INVALID_TBL;
    }

    DRV_TCAM_LOCK(lchip);
    p_db = &p_drv_master[lchip]->drv_io_tcam_db[TCAM_KEY_DRV_TYPE(lchip, tbl_id)];
    entry_num_each_idx = TCAM_KEY_SIZE(lchip, tbl_id)/p_db->tbl_size;
    p_db->drv_tcam_get_block_info(lchip, tbl_id, index*entry_num_each_idx, &blknum, &local_idx);
    tbl_words = p_db->tbl_size >> 2;
#if (SDB_DISABLE != SDB_MODE)
    if (DRV_READ_MEM_FROM_SER(p_db->tcam_mem_tbl_id))
    {
        uint32 *p_data = NULL;
        do
        {
           p_data = drv_sdb_read(lchip, p_db->tcam_mem_tbl_id, ((blknum << p_db->blk_shift) | local_idx), TABLE_ENTRY_OFFSET(lchip, p_db->tcam_mem_tbl_id), oper_bmp);
           p_mask = (uint32*)p_data + tbl_words;
           loop = 0;
            do
            {
               entry->data_entry[entry_idx * tbl_words + loop]  =  p_data[loop];
               entry->mask_entry[entry_idx * tbl_words + loop] = p_mask[loop];
               loop++;
            }while(loop <tbl_words);
            local_idx++;
            entry_idx++;
        }while(entry_idx <  entry_num_each_idx);
    }
   else
 #endif
    {
        uint32 ds[16] = {0};
        uint8 burst_op = 0;
        uint32 start_data_addr = 0;

        burst_op = !(TABLE_OP_TYPE(lchip, tbl_id)&Op_DisBurst) && p_drv_master[lchip]->burst_en;
 #if (1 == SDK_WORK_PLATFORM)
        start_data_addr = TABLE_INFO(lchip, p_db->tcam_mem_tbl_id).addrs[1] + ((blknum << p_db->blk_shift) | local_idx) *(p_db->hw_words<<2);
#else
          start_data_addr = TABLE_INFO(lchip, p_db->tcam_mem_tbl_id).addrs[0] + ((blknum << p_db->blk_shift) | local_idx) *(p_db->hw_words<<2);
#endif
        start_data_addr += burst_op;
       do
        {
          ret = ret ? ret: drv_usw_chip_read_sram_entry(lchip, ((uint64)oper_bmp << DRV_BITS_PER_WORD) | start_data_addr, (uint32*)ds,  TABLE_ENTRY_SIZE(lchip, p_db->tcam_mem_tbl_id));
          p_mask = (uint32*)ds + tbl_words;

          loop = 0;
     #if  (1 == SDK_WORK_PLATFORM)
         do
          {
              entry->data_entry[entry_idx * tbl_words + loop]  =  ds[loop];
              entry->mask_entry[entry_idx * tbl_words + loop] = p_mask[loop];
              loop++;
          }while(loop <tbl_words);
      #else
          do
          {
              mask_tmp = (p_mask[loop] ^ ds[loop]);
              entry->data_entry[entry_idx*tbl_words + loop]  =  (mask_tmp & ds[loop]);
              entry->mask_entry[entry_idx*tbl_words + loop] = mask_tmp;
              loop++;
          }while(loop <tbl_words);
   #endif
           entry_idx++;
           start_data_addr += (p_db->hw_words<<2);
        }while(entry_idx < entry_num_each_idx);
    }

    DRV_TCAM_UNLOCK(lchip);
    return ret;
}
/**
 @brief write tcam interface (include operate model and real tcam)
*/
int32
drv_usw_chip_tcam_tbl_write(uint8 lchip, uint32 index, uint32 cmd, uint8 oper_bmp, uint32 *value)
{
    uint32 tbl_id = 0;
    uint32 local_idx = 0;
    uint32 blknum = 0;
    drv_io_tcam_db_t* p_db = NULL;
    uint8 ds[DRV_DS_SIZE] = {0};
    tbl_entry_t *entry = (tbl_entry_t *)value;
    int32 ret = 0;
    uint8 entry_idx = 0;
    uint8 entry_num_each_idx = 0;
    uint8 tcam_type = 0;
    uint8 tcam_hash_en = 0;

#ifdef WARMBOOT
   if(p_drv_master[lchip]->wb_status == DRV_WB_STATUS_RELOADING)
    {
        return DRV_E_NONE;
    }
 #endif
    tbl_id = DRV_IOC_MEMID(cmd);
    if (TABLE_MAX_INDEX(lchip, tbl_id) <= index)
    {
        DRV_DBG_INFO("ERROR! (drv_usw_chip_tcam_tbl_read): chip-0x%x, tbl-0x%x, index-0x%x exceeds the max_index-0x%x.\n",
                    lchip, tbl_id, index, TABLE_MAX_INDEX(lchip, tbl_id));
        return DRV_E_INVALID_TBL;
    }

    tcam_type = TCAM_KEY_DRV_TYPE(lchip, tbl_id);
    p_db = &p_drv_master[lchip]->drv_io_tcam_db[tcam_type];

    entry_num_each_idx = TCAM_KEY_SIZE(lchip, tbl_id)/p_db->tbl_size;
    p_db->drv_tcam_get_block_info(lchip, tbl_id, index*entry_num_each_idx, &blknum, &local_idx);
    tcam_hash_en = p_drv_master[lchip]->p_ser_master && ((drv_ser_master_t*)p_drv_master[lchip]->p_ser_master)->tcam_scan_en;

    DRV_TCAM_LOCK(lchip);
    do
    {
        sal_memcpy(ds, (uint8*)entry->data_entry + entry_idx*p_db->tbl_size, p_db->tbl_size);
        sal_memcpy(ds + p_db->tbl_size, (uint8*)entry->mask_entry + entry_idx*p_db->tbl_size, p_db->tbl_size);
        drv_set_field32(lchip, p_db->tcam_mem_tbl_id, p_db->tcam_mem_fld_id, (uint32*)ds, 1);

#if (SDB_MEM_MODEL != SDB_MODE)
{
        uint8 burst_op =  !(TABLE_OP_TYPE(lchip, tbl_id)&Op_DisBurst) && p_drv_master[lchip]->burst_en;
        uint32 start_data_addr = 0;
#if (1 == SDK_WORK_PLATFORM)
            start_data_addr = TABLE_INFO(lchip, p_db->tcam_mem_tbl_id).addrs[1] + (((blknum << p_db->blk_shift) | local_idx) *(p_db->hw_words<<2));
#else
            start_data_addr = TABLE_INFO(lchip, p_db->tcam_mem_tbl_id).addrs[0] + (((blknum << p_db->blk_shift) | local_idx) *(p_db->hw_words<<2));
#endif

        start_data_addr = start_data_addr + burst_op;
        ret  = drv_usw_chip_write_sram_entry(lchip, ((uint64)oper_bmp << DRV_BITS_PER_WORD) | start_data_addr, (uint32*)ds, TABLE_ENTRY_SIZE(lchip, p_db->tcam_mem_tbl_id));
}
#endif

#if (SDB_DISABLE != SDB_MODE)
{
        if (!ret && (p_drv_master[lchip]->dev_type < DRV_TSINGMA_MX) && tcam_hash_en)
        {
            uint32 mem_id = 0, mem_offset = 0;
            drv_usw_ftm_table_id_2_mem_id(lchip, tbl_id, index, &mem_id, &mem_offset);
            _drv_usw_fresh_time_stamp(lchip, mem_id);
        }

        if (!ret && g_sdb_master[lchip] && g_sdb_master[lchip]->sdb_en)
        {
            DRV_MCHIP_SDB_API(lchip)->drv_sdb_write_api(lchip, p_db->tcam_mem_tbl_id, ((blknum << p_db->blk_shift) | local_idx), ds, TABLE_ENTRY_OFFSET(lchip, p_db->tcam_mem_tbl_id), oper_bmp);
        }
}
#endif
        /* set the bit value which corresponds to this entry equals to zero in the bitmap */
#if ((defined(EMULATION_ENV) && !defined(EMULATOR_ENV)))
        DRV_SER_SET_HASH_BMP(lchip, p_db->mem_id + blknum, local_idx, FALSE, 1, ds);
#else
        if ((p_drv_master[lchip]->dev_type >= DRV_TSINGMA_MX) && tcam_hash_en)
        {
            drv_ser_set_entry_bitmap(lchip, p_db->mem_id+blknum,  local_idx, oper_bmp);
        }
#endif
        local_idx++;
        entry_idx++;
    }while(entry_idx < entry_num_each_idx);

    DRV_TCAM_UNLOCK(lchip);

    return ret;
}


/**
 @brief remove tcam entry interface (include operate model and real tcam)
*/
int32
drv_usw_chip_tcam_tbl_remove(uint8 lchip, uint32 index, uint32 cmd, uint8 oper_bmp, uint32 *value)
{
    uint32 tbl_id = 0;
    uint8 entry_idx = 0;
    uint8 entry_num_each_idx = 0;
    uint8 tcam_type = 0;

    uint32 blknum = 0;
    uint32 local_idx = 0;
    drv_io_tcam_db_t* p_db = NULL;
    uint8 ds[DRV_DS_SIZE] = {0};
    uint8 tcam_hash_en = 0;

    tbl_id = DRV_IOC_MEMID(cmd);
    if (TABLE_MAX_INDEX(lchip, tbl_id) <= index)
    {
        DRV_DBG_INFO("ERROR! (drv_usw_chip_tcam_tbl_read): chip-0x%x, tbl-0x%x, index-0x%x exceeds the max_index-0x%x.\n",
                    lchip, tbl_id, index, TABLE_MAX_INDEX(lchip, tbl_id));
        return DRV_E_INVALID_TBL;
    }

    tcam_type = TCAM_KEY_DRV_TYPE(lchip, tbl_id);
    p_db = &p_drv_master[lchip]->drv_io_tcam_db[tcam_type];
    tcam_hash_en = p_drv_master[lchip]->p_ser_master && ((drv_ser_master_t*)p_drv_master[lchip]->p_ser_master)->tcam_scan_en;

    entry_num_each_idx = TCAM_KEY_SIZE(lchip, tbl_id)/p_db->tbl_size;
    p_db->drv_tcam_get_block_info(lchip, tbl_id, index*entry_num_each_idx, &blknum, &local_idx);

    DRV_TCAM_LOCK(lchip);
    do
    {
#if (SDB_MEM_MODEL != SDB_MODE)
        uint8 burst_op = !(TABLE_OP_TYPE(lchip, tbl_id)&Op_DisBurst) && p_drv_master[lchip]->burst_en;
        uint32 start_data_addr = 0;
#if (1 == SDK_WORK_PLATFORM)
            start_data_addr = TABLE_INFO(lchip, p_db->tcam_mem_tbl_id).addrs[1] + ((blknum << p_db->blk_shift) | local_idx) *p_db->hw_words*DRV_BYTES_PER_WORD;
#else
            start_data_addr = TABLE_INFO(lchip, p_db->tcam_mem_tbl_id).addrs[0] + ((blknum << p_db->blk_shift) | local_idx) *p_db->hw_words*DRV_BYTES_PER_WORD;
#endif

        start_data_addr = start_data_addr + burst_op;
        DRV_IF_ERROR_RETURN_WITH_UNLOCK(drv_usw_chip_write_sram_entry(lchip, ((uint64)oper_bmp << DRV_BITS_PER_WORD) | start_data_addr, (uint32*)ds, TABLE_ENTRY_SIZE(lchip, p_db->tcam_mem_tbl_id)), p_drv_master[lchip]->p_tcam_write_mutex);
#endif

#if (SDB_DISABLE != SDB_MODE)
{
        if ((p_drv_master[lchip]->dev_type < DRV_TSINGMA_MX) && tcam_hash_en)
        {
            uint32 mem_id = 0, mem_offset = 0;
            drv_usw_ftm_table_id_2_mem_id(lchip, tbl_id, index, &mem_id, &mem_offset);
            _drv_usw_fresh_time_stamp(lchip, mem_id);
        }
        if (g_sdb_master[lchip] && g_sdb_master[lchip]->sdb_en)
        {
            DRV_MCHIP_SDB_API(lchip)->drv_sdb_write_api(lchip, p_db->tcam_mem_tbl_id, ((blknum << p_db->blk_shift) | local_idx), ds, TABLE_ENTRY_OFFSET(lchip, p_db->tcam_mem_tbl_id), oper_bmp);
        }
}
#endif
        /* set the bit value which corresponds to this entry equals to zero in the bitmap */
#if defined(EMULATION_ENV) && !defined(EMULATOR_ENV)
        DRV_SER_SET_HASH_BMP(lchip, p_db->mem_id+blknum, local_idx, FALSE, 1, ds);
#else
        if ((p_drv_master[lchip]->dev_type >= DRV_TSINGMA_MX) && tcam_hash_en)
        {
            drv_ser_set_entry_bitmap(lchip, p_db->mem_id+blknum,  local_idx, oper_bmp);
        }
#endif
        local_idx++;
       entry_idx++;
    }while(entry_idx < entry_num_each_idx);

    DRV_TCAM_UNLOCK(lchip);
    return DRV_E_NONE;
}

/**
 @brief pcie direct read memory offset
 len units : 4B
*/
STATIC int32
_drv_usw_chip_read_pcie_mem(uint8 lchip, uint32 pci_addr, uint32* data, int32 len)
{
    uint32 count = 0;
    uint32 addr_ctl = 0;
    uint32 offset = pci_addr;
    uint32 addr_ofst = pci_addr;

    /*oper PcieAddrCtl, if pci_addr >= 0x400_0000, map to 0x200_0000*/
    offset = (pci_addr >> 24) & 0xE;
    addr_ctl = (0xFC00 << 16) | offset;
    /*map to 0x0200_0000-0x03FF_FFFF*/
    offset <<= 24;
    if ((pci_addr >> 24) >= 4)
    {
        addr_ofst = pci_addr - offset + 0x2000000;
    }
    g_dal_op.pci_write(DRV_MAP_LDEV(lchip), DRV_PCI_ADDR_CTL, addr_ctl);

    do
    {
        g_dal_op.pci_read(DRV_MAP_LDEV(lchip), addr_ofst + (count << 2), &data[count]);
        count++;
    }while (--len);
    addr_ctl = (0xFC00 << 16) | 0;
    g_dal_op.pci_write(DRV_MAP_LDEV(lchip), DRV_PCI_ADDR_CTL, addr_ctl);
    return DRV_E_NONE;
}
STATIC int32
_drv_usw_chip_write_pcie_mem(uint8 lchip, uint32 pci_addr, uint32* data, int32 len)
{
    uint32 count = 0;
    uint32 offset = pci_addr;
    uint32 addr_ofst = pci_addr;
    uint32 addr_ctl = 0;

    /*oper PcieAddrCtl, if pci_addr >= 0x400_0000, map to 0x200_0000*/
    offset = (pci_addr >> 24) & 0xE;
    addr_ctl = (0xFC00 << 16) | offset;
    /*map to 0x0200_0000-0x03FF_FFFF*/
    offset <<= 24;
    if ((pci_addr >> 24) >= 4)
    {
        addr_ofst = pci_addr - offset + 0x2000000;
    }
    g_dal_op.pci_write(DRV_MAP_LDEV(lchip), DRV_PCI_ADDR_CTL, addr_ctl);

    do
    {
        g_dal_op.pci_write(DRV_MAP_LDEV(lchip), addr_ofst + (count << 2), data[count]);
        count++;
    } while (--len);
    addr_ctl = (0xFC00 << 16) | 0;
    g_dal_op.pci_write(DRV_MAP_LDEV(lchip), DRV_PCI_ADDR_CTL, addr_ctl);
    return DRV_E_NONE;
}

int32
drv_usw_chip_read_eunit_mem(uint8 lchip, uint32 pci_addr, uint32* data, int32 len)
{

    if (!len)
    {
        return DRV_E_INVALID_PARAMETER;
    }
    DRV_ENTRY_LOCK(lchip);
    if (p_drv_master[lchip]->access_type == DRV_PCI_ACCESS)
    {
        _drv_usw_chip_read_pcie_mem(lchip, pci_addr, data, len);
    }
    else if (p_drv_master[lchip]->access_type == DRV_I2C_ACCESS)
    {

    }
    DRV_ENTRY_UNLOCK(lchip);
    return DRV_E_NONE;
}
/**
 @brief pcie direct read memory offset
 len units : 4B
*/
int32
drv_usw_chip_write_eunit_mem(uint8 lchip, uint32 pci_addr, uint32* data, int32 len)
{

    if (!len)
    {
        return DRV_E_INVALID_PARAMETER;
    }
    
    DRV_ENTRY_LOCK(lchip);
    if (p_drv_master[lchip]->access_type == DRV_PCI_ACCESS)
    {
        _drv_usw_chip_write_pcie_mem(lchip, pci_addr, data, len);
    }
    else if (p_drv_master[lchip]->access_type == DRV_I2C_ACCESS)
    {

    }
    DRV_ENTRY_UNLOCK(lchip);
    return DRV_E_NONE;
}

int32
drv_chip_dyn_tbl_op_type_init(uint8 lchip)
{
    TABLE_IOCTL_TYPE(lchip, SharedPcsSoftRst0_t) = DRV_TBL_TYPE_MCU;
    TABLE_IOCTL_TYPE(lchip, SharedPcsSoftRst1_t) = DRV_TBL_TYPE_MCU;
    TABLE_IOCTL_TYPE(lchip, QsgmiiPcsSoftRst0_t) = DRV_TBL_TYPE_MCU;
    TABLE_IOCTL_TYPE(lchip, QsgmiiPcsSoftRst1_t) = DRV_TBL_TYPE_MCU;
    TABLE_IOCTL_TYPE(lchip, QsgmiiPcsSoftRst2_t) = DRV_TBL_TYPE_MCU;
    TABLE_IOCTL_TYPE(lchip, QsgmiiPcsSoftRst3_t) = DRV_TBL_TYPE_MCU;
    TABLE_IOCTL_TYPE(lchip, QsgmiiPcsSoftRst4_t) = DRV_TBL_TYPE_MCU;
    TABLE_IOCTL_TYPE(lchip, QsgmiiPcsSoftRst5_t) = DRV_TBL_TYPE_MCU;
    TABLE_IOCTL_TYPE(lchip, QsgmiiPcsSoftRst6_t) = DRV_TBL_TYPE_MCU;
    TABLE_IOCTL_TYPE(lchip, QsgmiiPcsSoftRst7_t) = DRV_TBL_TYPE_MCU;
    TABLE_IOCTL_TYPE(lchip, UsxgmiiPcsSoftRst0_t) = DRV_TBL_TYPE_MCU;
    TABLE_IOCTL_TYPE(lchip, UsxgmiiPcsSoftRst1_t) = DRV_TBL_TYPE_MCU;
    TABLE_IOCTL_TYPE(lchip, UsxgmiiPcsSoftRst2_t) = DRV_TBL_TYPE_MCU;
    TABLE_IOCTL_TYPE(lchip, UsxgmiiPcsSoftRst3_t) = DRV_TBL_TYPE_MCU;
    TABLE_IOCTL_TYPE(lchip, UsxgmiiPcsSoftRst4_t) = DRV_TBL_TYPE_MCU;
    TABLE_IOCTL_TYPE(lchip, UsxgmiiPcsSoftRst5_t) = DRV_TBL_TYPE_MCU;
    TABLE_IOCTL_TYPE(lchip, UsxgmiiPcsSoftRst6_t) = DRV_TBL_TYPE_MCU;
    TABLE_IOCTL_TYPE(lchip, UsxgmiiPcsSoftRst7_t) = DRV_TBL_TYPE_MCU;
    TABLE_IOCTL_TYPE(lchip, SharedPcsSoftRst2_t) = DRV_TBL_TYPE_MCU;
    TABLE_IOCTL_TYPE(lchip, SharedPcsSoftRst3_t) = DRV_TBL_TYPE_MCU;
    TABLE_IOCTL_TYPE(lchip, QsgmiiPcsSoftRst8_t) = DRV_TBL_TYPE_MCU;
    TABLE_IOCTL_TYPE(lchip, QsgmiiPcsSoftRst9_t) = DRV_TBL_TYPE_MCU;
    TABLE_IOCTL_TYPE(lchip, QsgmiiPcsSoftRst10_t) = DRV_TBL_TYPE_MCU;
    TABLE_IOCTL_TYPE(lchip, QsgmiiPcsSoftRst11_t) = DRV_TBL_TYPE_MCU;
    TABLE_IOCTL_TYPE(lchip, UsxgmiiPcsSoftRst8_t) = DRV_TBL_TYPE_MCU;
    TABLE_IOCTL_TYPE(lchip, UsxgmiiPcsSoftRst9_t) = DRV_TBL_TYPE_MCU;
    TABLE_IOCTL_TYPE(lchip, UsxgmiiPcsSoftRst10_t) = DRV_TBL_TYPE_MCU;
    TABLE_IOCTL_TYPE(lchip, UsxgmiiPcsSoftRst11_t) = DRV_TBL_TYPE_MCU;
    TABLE_IOCTL_TYPE(lchip, SharedPcsSoftRst4_t) = DRV_TBL_TYPE_MCU;
    TABLE_IOCTL_TYPE(lchip, SharedPcsSoftRst5_t) = DRV_TBL_TYPE_MCU;
    TABLE_IOCTL_TYPE(lchip, UsxgmiiPcsSoftRst6_t) = DRV_TBL_TYPE_MCU;
    TABLE_IOCTL_TYPE(lchip, UsxgmiiPcsSoftRst7_t) = DRV_TBL_TYPE_MCU;

    TABLE_IOCTL_TYPE(lchip, BufRetrvPostBrPbIntfInit_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, BufRetrvPreBrFifoCtl_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, BufRetrvPreBrInit_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, BufStoreAqmSeed_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, BufStoreErmDebugStats_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, BufStoreErmInit_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, CtcBufStoreErmSliceCtlReset_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, DsAqmActionProfile_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, DsAqmPortCfg_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, DsAqmPortThrdProfile_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, DsAqmPortThrdQuantProfile_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, DsAqmQueueCfg_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, DsAqmQueueThrdProfile_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, DsAqmQueueThrdProfileId_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, DsAqmQueueThrdQuantProfile_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, DsErmAqmQueueCfg_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, DsErmAqmQueueThrdProfile_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, DsErmAqmQueueThrdQuantProfile_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, DsErmDmaThrdProfileUc_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, DsErmPortMbCfg_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, DsErmPortScThrdProfileUc_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, DsErmPortTcMbCfg_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, DsErmPortTcStallThrdProfile_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, DsErmPortThrdProfileUc_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, DsErmQueueThrdProfileUc_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, DsQMgrChanCreditThrd_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, DsQMgrChanWeight_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, DsQMgrDeqChanSchCfg_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, DsQMgrGrpConfigMc_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, DsQMgrGrpConfigUc_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, DsQMgrQueCreditHighConfig_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, DsQMgrQueCreditLowConfig_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, DsQMgrQueCreditMidConfig_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, DsQMgrQueIdMap_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, DsQMgrQueIdReMap_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, DsQMgrQueStateMc_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, DsQMgrQueStateUc_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, DsQMgrRdChanCfg_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, DsQMgrRdCreditUnit_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, DsQMgrRdFlowCtlMap0_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, DsQMgrRdFlowCtlMap1_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, DsQMgrRdFlowCtlMapDma_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, ErmResrcStateInformScanCtl_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, ErmResrcStateScanCtl_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, PreBrChanBufCredit_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, PreBrChanBufPtrMode_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, PreBrChanBufThrd_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, PreBrCreditCtl_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, PreBrDPPktMsgVoQCtl_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, PreBrWrrCtl_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, PreBrWrrDebugCtl_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, PreBufferRetrieveCtl_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, PreBufferRetrieveXCtl_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, QMgrDeqChanCtl_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, QMgrDeqChanIdCfg_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, QMgrDeqChanInit_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, QMgrDeqCreditCtl_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, QMgrDeqCreditScanCtl_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, QMgrDeqFlowCtlEnMc_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, QMgrDeqFlowCtlEnUc_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, QMgrDeqGrpMcInit_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, QMgrDeqGrpMcScanCtl_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, QMgrDeqGrpUcInit_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, QMgrDeqGrpUcScanCtl_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, QMgrDeqIntfWeightCfg_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, QMgrDeqMiscCtlMc_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, QMgrDeqMiscCtlUc_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, QMgrDmaQueCreditConfig_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, QMgrGrpPpsModeCtlMc_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, QMgrGrpPpsModeCtlUc_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, QMgrLinkListMcInit_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, QMgrLinkListUcInit_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, QMgrRdChanDiscardCtl_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, QMgrRdCtl_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, QMgrRdDmaCreditUnitCtl_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, QMgrRdMonCtl_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, QMgrRdPktUnitCtl_t) = DRV_TBL_TYPE_M_CORE;

    TABLE_IOCTL_TYPE(lchip, DsErmQueueLimitedThrdProfileMc_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, DsErmQueueGuaranteedThrdProfileMc_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, DsErmPortLimitedThrdProfileMc_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, DsErmPortGuaranteedThrdProfileMc_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, DsErmPortScLimitedThrdProfileMc_t) = DRV_TBL_TYPE_M_CORE;
    TABLE_IOCTL_TYPE(lchip, DsErmPortScGuaranteedThrdProfileMc_t) = DRV_TBL_TYPE_M_CORE;
    
    if(DRV_IS_TMG(lchip))
    {
        TABLE_IOCTL_TYPE(lchip,IpeHeaderAdjustPhyPortMap_t) = DRV_TBL_TYPE_CHA_MAP;
        TABLE_IOCTL_TYPE(lchip,IpePhyPortMuxCtl_t) = DRV_TBL_TYPE_CHA_MAP;
        TABLE_IOCTL_TYPE(lchip,DsSrcChannel_t) = DRV_TBL_TYPE_CHA_MAP;
        TABLE_IOCTL_TYPE(lchip,DsChannelToEcmpGroupMap_t) = DRV_TBL_TYPE_CHA_MAP;
        TABLE_IOCTL_TYPE(lchip,DsDestChannel_t) = DRV_TBL_TYPE_CHA_MAP;
        TABLE_IOCTL_TYPE(lchip,DsLatencyMon0_t) = DRV_TBL_TYPE_CHA_MAP;
        TABLE_IOCTL_TYPE(lchip,DsLatencyMon1_t) = DRV_TBL_TYPE_CHA_MAP;
        TABLE_IOCTL_TYPE(lchip,EpeHeaderEditPhyPortMap_t) = DRV_TBL_TYPE_CHA_MAP;
        TABLE_IOCTL_TYPE(lchip,DsPacketHeaderEditTunnel_t) = DRV_TBL_TYPE_CHA_MAP;
        TABLE_IOCTL_TYPE(lchip,EpeHeaderAdjustPhyPortMap_t) = DRV_TBL_TYPE_CHA_MAP;
        TABLE_IOCTL_TYPE(lchip,MetFifoLinkStatus_t) = DRV_TBL_TYPE_CHA_MAP;
        TABLE_IOCTL_TYPE(lchip,DsMetPortChannelLag_t) = DRV_TBL_TYPE_CHA_MAP;
        TABLE_IOCTL_TYPE(lchip,DsApsChannelMap_t) = DRV_TBL_TYPE_CHA_MAP;
        TABLE_IOCTL_TYPE(lchip,DsQWriteDestPortChannelMap_t) = DRV_TBL_TYPE_CHA_MAP;
        TABLE_IOCTL_TYPE(lchip,DsQWriteSubQueChannelMap_t) = DRV_TBL_TYPE_CHA_MAP;
        TABLE_IOCTL_TYPE(lchip,EcmpDlbChanStateCtl_t) = DRV_TBL_TYPE_CHA_MAP;
        TABLE_IOCTL_TYPE(lchip,EcmpDlbChanLoadQualityS0_t) = DRV_TBL_TYPE_CHA_MAP;
        TABLE_IOCTL_TYPE(lchip,EcmpDlbChanLoadQualityS1_t) = DRV_TBL_TYPE_CHA_MAP;
        TABLE_IOCTL_TYPE(lchip,EcmpDlbChanLoadQualityS2_t) = DRV_TBL_TYPE_CHA_MAP;
        TABLE_IOCTL_TYPE(lchip,EcmpDlbChanLoadQualityS3_t) = DRV_TBL_TYPE_CHA_MAP;
        TABLE_IOCTL_TYPE(lchip,DsLatencyMon0_t) = DRV_TBL_TYPE_CHA_MAP;
        TABLE_IOCTL_TYPE(lchip,LagDlbChanLoadQualityS0_t) = DRV_TBL_TYPE_CHA_MAP;
        TABLE_IOCTL_TYPE(lchip,LagDlbChanLoadQualityS1_t) = DRV_TBL_TYPE_CHA_MAP;
        TABLE_IOCTL_TYPE(lchip,LagDlbChanLoadQualityS2_t) = DRV_TBL_TYPE_CHA_MAP;
        TABLE_IOCTL_TYPE(lchip,LagDlbChanLoadQualityS3_t) = DRV_TBL_TYPE_CHA_MAP;
        TABLE_IOCTL_TYPE(lchip,LagEngineLinkState_t) = DRV_TBL_TYPE_CHA_MAP;
        TABLE_IOCTL_TYPE(lchip,DsLinkAggregateChannel_t) = DRV_TBL_TYPE_CHA_MAP;
        TABLE_IOCTL_TYPE(lchip,CflexLagLinkSelfHealingSet_t) = DRV_TBL_TYPE_CHA_MAP;
        TABLE_IOCTL_TYPE(lchip,LagEngineChannelByteCounterHisS0_t) = DRV_TBL_TYPE_CHA_MAP;
        TABLE_IOCTL_TYPE(lchip,LagEngineChannelByteCounterCurS0_t) = DRV_TBL_TYPE_CHA_MAP;
        TABLE_IOCTL_TYPE(lchip,LagEngineChannelByteCounterHisS1_t) = DRV_TBL_TYPE_CHA_MAP;
        TABLE_IOCTL_TYPE(lchip,LagEngineChannelByteCounterCurS1_t) = DRV_TBL_TYPE_CHA_MAP;
        TABLE_IOCTL_TYPE(lchip,LagEngineChannelByteCounterHisS2_t) = DRV_TBL_TYPE_CHA_MAP;
        TABLE_IOCTL_TYPE(lchip,LagEngineChannelByteCounterCurS2_t) = DRV_TBL_TYPE_CHA_MAP;
        TABLE_IOCTL_TYPE(lchip,LagEngineChannelByteCounterHisS3_t) = DRV_TBL_TYPE_CHA_MAP;
        TABLE_IOCTL_TYPE(lchip,LagEngineChannelByteCounterCurS3_t) = DRV_TBL_TYPE_CHA_MAP;
    }
    return DRV_E_NONE;
}

int32
drv_chip_common_init(uint8 lchip)
{
#if (0 == SDK_WORK_PLATFORM)
    uint32 value = 0;
    uint32 ldev = drv_map_ldev[lchip];
#endif

    if (lchip >= DRV_MAX_CHIP_NUM)
    {
        return DRV_E_NOT_INIT;
    }

    if (!p_drv_master[lchip])
    {
        return DRV_E_INIT_FAILED;
    }

#if (defined(TSINGMA_MX) || defined(TSINGMA_GX)  || defined(ARCTIC))&& (1 == SDK_WORK_PLATFORM)
    p_drv_master[lchip]->burst_en = 0;

#else
    p_drv_master[lchip]->burst_en = 1;

#endif

#if (0 == SDK_WORK_PLATFORM)
    if ((p_drv_master[lchip]->dev_type == DRV_TSINGMA_MX) || (p_drv_master[lchip]->dev_type == DRV_TSINGMA_GX) || (p_drv_master[lchip]->dev_type == DRV_ARCTIC))
    {
        if (g_dal_op.pci_read)
        {
            g_dal_op.pci_read(ldev, DRV_PCI_MEM_MAP_MODE, &value);
        }
        value = value | 0x1;
        if (g_dal_op.pci_write)
        {
            g_dal_op.pci_write(ldev, DRV_PCI_MEM_MAP_MODE, value);
        }
    }
#endif
    if(p_drv_master[lchip]->dev_type == DRV_TSINGMA_GX)
	{
        p_drv_master[lchip]->drv_io_tcam_db[DRV_IO_TCAM_TYPE_LPM].drv_tcam_get_block_info = drv_tmg_lpm_tcam_get_blknum_index;
    }
    else
    {
        p_drv_master[lchip]->drv_io_tcam_db[DRV_IO_TCAM_TYPE_LPM].drv_tcam_get_block_info = drv_usw_lpm_tcam_get_blknum_index;
    }
    if (p_drv_master[lchip]->dev_type >= DRV_ARCTIC)
    {
        DRV_IF_ERROR_RETURN(drv_chip_dyn_tbl_op_type_init(lchip));
    }
    DRV_IF_ERROR_RETURN(drv_usw_lpm_tcam_init_blknum(lchip));

    /* initialize tcam I/O mutex */
    DRV_IF_ERROR_RETURN(drv_usw_chip_tcam_mutex_init(lchip));

    /* initialize pci I/O mutex */
    DRV_IF_ERROR_RETURN(drv_usw_chip_pci_mutex_init(lchip));

    /* initialize i2c I/O mutex */
    DRV_IF_ERROR_RETURN(drv_usw_chip_i2c_mutex_init(lchip));

    /* initialize Hss I/O mutex */
    DRV_IF_ERROR_RETURN(drv_usw_chip_hss_mutex_init(lchip));

    /* initialize Acc I/O mutex */
    DRV_IF_ERROR_RETURN(drv_usw_chip_acc_mutex_init(lchip));

    /* initialize mmap I/O mutex */
    DRV_IF_ERROR_RETURN(drv_usw_chip_mmap_mutex_init(lchip));

    /* */
#ifdef DUET2
#if (0 == SDK_WORK_PLATFORM)
    if (p_drv_master[lchip]->dev_type == DRV_DUET2)
    {
        extern dal_op_t g_dal_op;
        uint32 value = 0;
        g_dal_op.pci_read(ldev, 0x4c, &value);
        value = value | (1 << 28);
        g_dal_op.pci_write(ldev, 0x4c, value);
    }
#endif
#endif
    return DRV_E_NONE;
}

int32
drv_chip_pci_intf_adjust_en(uint8 lchip, uint8 enable)
{
    uint32 value = 0;
    uint32 value_tmp = 0;
    uint32 addr = 0;

    /*read/write addr 0x30 and set bit15*/
    addr = 0x30<<16;
    g_dal_op.pci_write_ext(DRV_MAP_LDEV(lchip), 0xc4, 1, &addr);
    g_dal_op.pci_read_ext(DRV_MAP_LDEV(lchip), 0xcc, 1, &value);
    value = value | (1<<15);
    g_dal_op.pci_write_ext(DRV_MAP_LDEV(lchip), 0xc8, 1, &value);
    addr = 0x30<<16 |0xF3;
    g_dal_op.pci_write_ext(DRV_MAP_LDEV(lchip), 0xc4, 1, &addr);

    sal_task_sleep(1);

    /*read/write addr 0x30 and bit[16:21]+2*/
    addr = 0x30<<16;
    g_dal_op.pci_write_ext(DRV_MAP_LDEV(lchip), 0xc4, 1, &addr);
    g_dal_op.pci_read_ext(DRV_MAP_LDEV(lchip), 0xcc, 1, &value);
    value_tmp = enable?((value&0x03F0000) + (1<<17)):((value&0x03F0000) - (1<<17));
    value = (value&0xFFC0FFFF) | (value_tmp&0x003F0000);
    g_dal_op.pci_write_ext(DRV_MAP_LDEV(lchip), 0xc8, 1, &value);
    addr = 0x30<<16 | 0xF3;
    g_dal_op.pci_write_ext(DRV_MAP_LDEV(lchip), 0xc4, 1, &addr);

    sal_task_sleep(1);

    /*read/write addr 0x3c and set bit30*/
    addr = 0x3C<<16;
    g_dal_op.pci_write_ext(DRV_MAP_LDEV(lchip), 0xc4, 1, &addr);
    g_dal_op.pci_read_ext(DRV_MAP_LDEV(lchip), 0xcc, 1, &value);
    value = value | (1<<30);
    g_dal_op.pci_write_ext(DRV_MAP_LDEV(lchip), 0xc8, 1, &value);
    addr = 0x3C<<16 | 0xF3;
    g_dal_op.pci_write_ext(DRV_MAP_LDEV(lchip), 0xc4, 1, &addr);

    return DRV_E_NONE;
}
#endif

